xref: /FreeRTOS-Plus-TCP-v4.0.0/source/portable/NetworkInterface/STM32Hxx/stm32hxx_hal_eth.c (revision 172733b5b79e968b6b3f2790692d8b9574e98e4e)
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  Set the ETH MAC (L2) Filters configuration.
2176  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2177  *         the configuration information for ETHERNET module
2178  * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2179  *         the configuration of the ETH MAC filters.
2180  * @retval HAL status
2181  */
HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2182         HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig( ETH_HandleTypeDef * heth,
2183                                                       ETH_MACFilterConfigTypeDef * pFilterConfig )
2184         {
2185             uint32_t filterconfig;
2186 
2187             if( pFilterConfig == NULL )
2188             {
2189                 return HAL_ERROR;
2190             }
2191 
2192             filterconfig = ( ( uint32_t ) pFilterConfig->PromiscuousMode |
2193                              ( ( uint32_t ) pFilterConfig->HashUnicast << 1 ) |
2194                              ( ( uint32_t ) pFilterConfig->HashMulticast << 2 ) |
2195                              ( ( uint32_t ) pFilterConfig->DestAddrInverseFiltering << 3 ) |
2196                              ( ( uint32_t ) pFilterConfig->PassAllMulticast << 4 ) |
2197                              ( ( uint32_t ) ( ( pFilterConfig->BroadcastFilter == DISABLE ) ? 1U : 0U ) << 5 ) |
2198                              ( ( uint32_t ) pFilterConfig->SrcAddrInverseFiltering << 8 ) |
2199                              ( ( uint32_t ) pFilterConfig->SrcAddrFiltering << 9 ) |
2200                              ( ( uint32_t ) pFilterConfig->HachOrPerfectFilter << 10 ) |
2201                              ( ( uint32_t ) pFilterConfig->ReceiveAllMode << 31 ) |
2202                              pFilterConfig->ControlPacketsFilter );
2203 
2204             MODIFY_REG( heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig );
2205 
2206             return HAL_OK;
2207         }
2208 
2209 /**
2210  * @brief  Get the ETH MAC (L2) Filters configuration.
2211  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2212  *         the configuration information for ETHERNET module
2213  * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2214  *         the configuration of the ETH MAC filters.
2215  * @retval HAL status
2216  */
HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2217         HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig( ETH_HandleTypeDef * heth,
2218                                                       ETH_MACFilterConfigTypeDef * pFilterConfig )
2219         {
2220             if( pFilterConfig == NULL )
2221             {
2222                 return HAL_ERROR;
2223             }
2224 
2225             pFilterConfig->PromiscuousMode = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PR ) ) > 0U ) ? ENABLE : DISABLE;
2226             pFilterConfig->HashUnicast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HUC ) >> 1 ) > 0U ) ? ENABLE : DISABLE;
2227             pFilterConfig->HashMulticast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HMC ) >> 2 ) > 0U ) ? ENABLE : DISABLE;
2228             pFilterConfig->DestAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_DAIF ) >> 3 ) > 0U ) ? ENABLE : DISABLE;
2229             pFilterConfig->PassAllMulticast = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PM ) >> 4 ) > 0U ) ? ENABLE : DISABLE;
2230             pFilterConfig->BroadcastFilter = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_DBF ) >> 5 ) == 0U ) ? ENABLE : DISABLE;
2231             pFilterConfig->ControlPacketsFilter = READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_PCF );
2232             pFilterConfig->SrcAddrInverseFiltering = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_SAIF ) >> 8 ) > 0U ) ? ENABLE : DISABLE;
2233             pFilterConfig->SrcAddrFiltering = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_SAF ) >> 9 ) > 0U ) ? ENABLE : DISABLE;
2234             pFilterConfig->HachOrPerfectFilter = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_HPF ) >> 10 ) > 0U ) ? ENABLE : DISABLE;
2235             pFilterConfig->ReceiveAllMode = ( ( READ_BIT( heth->Instance->MACPFR, ETH_MACPFR_RA ) >> 31 ) > 0U ) ? ENABLE : DISABLE;
2236 
2237             return HAL_OK;
2238         }
2239 
2240 /**
2241  * @brief  Set the source MAC Address to be matched.
2242  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2243  *         the configuration information for ETHERNET module
2244  * @param  AddrNbr: The MAC address to configure
2245  *          This parameter must be a value of the following:
2246  *            ETH_MAC_ADDRESS1
2247  *            ETH_MAC_ADDRESS2
2248  *            ETH_MAC_ADDRESS3
2249  * @param  pMACAddr: Pointer to MAC address buffer data (6 bytes)
2250  * @retval HAL status
2251  */
HAL_ETH_SetSourceMACAddrMatch(ETH_HandleTypeDef * heth,uint32_t AddrNbr,uint8_t * pMACAddr)2252         HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch( ETH_HandleTypeDef * heth,
2253                                                          uint32_t AddrNbr,
2254                                                          uint8_t * pMACAddr )
2255         {
2256             uint32_t macaddrhr, macaddrlr;
2257 
2258             if( pMACAddr == NULL )
2259             {
2260                 return HAL_ERROR;
2261             }
2262 
2263             /* Get mac addr high reg offset */
2264             macaddrhr = ( ( uint32_t ) &( heth->Instance->MACA0HR ) + AddrNbr );
2265             /* Get mac addr low reg offset */
2266             macaddrlr = ( ( uint32_t ) &( heth->Instance->MACA0LR ) + AddrNbr );
2267 
2268             /* Set MAC addr bits 32 to 47 */
2269             ( *( __IO uint32_t * ) macaddrhr ) = ( ( ( uint32_t ) ( pMACAddr[ 5 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 4 ] );
2270             /* Set MAC addr bits 0 to 31 */
2271             ( *( __IO uint32_t * ) macaddrlr ) = ( ( ( uint32_t ) ( pMACAddr[ 3 ] ) << 24 ) | ( ( uint32_t ) ( pMACAddr[ 2 ] ) << 16 ) |
2272                                                    ( ( uint32_t ) ( pMACAddr[ 1 ] ) << 8 ) | ( uint32_t ) pMACAddr[ 0 ] );
2273 
2274             /* Enable address and set source address bit */
2275             ( *( __IO uint32_t * ) macaddrhr ) |= ( ETH_MACAHR_SA | ETH_MACAHR_AE );
2276 
2277             return HAL_OK;
2278         }
2279 
2280 /**
2281  * @brief  Set the ETH Hash Table Value.
2282  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2283  *         the configuration information for ETHERNET module
2284  * @param  pHashTable: pointer to a table of two 32 bit values, that contains
2285  *         the 64 bits of the hash table.
2286  * @retval HAL status
2287  */
HAL_ETH_SetHashTable(ETH_HandleTypeDef * heth,uint32_t * pHashTable)2288         HAL_StatusTypeDef HAL_ETH_SetHashTable( ETH_HandleTypeDef * heth,
2289                                                 uint32_t * pHashTable )
2290         {
2291             if( pHashTable == NULL )
2292             {
2293                 return HAL_ERROR;
2294             }
2295 
2296             heth->Instance->MACHT0R = pHashTable[ 0 ];
2297             heth->Instance->MACHT1R = pHashTable[ 1 ];
2298 
2299             return HAL_OK;
2300         }
2301 
2302 /**
2303  * @brief  Set the VLAN Identifier for Rx packets
2304  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2305  *         the configuration information for ETHERNET module
2306  * @param  ComparisonBits: 12 or 16 bit comparison mode
2307  *          must be a value of @ref ETH_VLAN_Tag_Comparison
2308  * @param  VLANIdentifier: VLAN Identifier value
2309  * @retval None
2310  */
HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t ComparisonBits,uint32_t VLANIdentifier)2311         void HAL_ETH_SetRxVLANIdentifier( ETH_HandleTypeDef * heth,
2312                                           uint32_t ComparisonBits,
2313                                           uint32_t VLANIdentifier )
2314         {
2315             if( ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT )
2316             {
2317                 MODIFY_REG( heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier );
2318                 CLEAR_BIT( heth->Instance->MACVTR, ETH_MACVTR_ETV );
2319             }
2320             else
2321             {
2322                 MODIFY_REG( heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier );
2323                 SET_BIT( heth->Instance->MACVTR, ETH_MACVTR_ETV );
2324             }
2325         }
2326 
2327 /**
2328  * @brief  Enters the Power down mode.
2329  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2330  *         the configuration information for ETHERNET module
2331  * @param  pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2332  *         that contains the Power Down configration
2333  * @retval None.
2334  */
HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef * heth,ETH_PowerDownConfigTypeDef * pPowerDownConfig)2335         void HAL_ETH_EnterPowerDownMode( ETH_HandleTypeDef * heth,
2336                                          ETH_PowerDownConfigTypeDef * pPowerDownConfig )
2337         {
2338             uint32_t powerdownconfig;
2339 
2340             powerdownconfig = ( ( ( uint32_t ) pPowerDownConfig->MagicPacket << 1 ) |
2341                                 ( ( uint32_t ) pPowerDownConfig->WakeUpPacket << 2 ) |
2342                                 ( ( uint32_t ) pPowerDownConfig->GlobalUnicast << 9 ) |
2343                                 ( ( uint32_t ) pPowerDownConfig->WakeUpForward << 10 ) |
2344                                 ETH_MACPCSR_PWRDWN );
2345 
2346             /* Enable PMT interrupt */
2347             __HAL_ETH_MAC_ENABLE_IT( heth, ETH_MACIER_PMTIE );
2348 
2349             MODIFY_REG( heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig );
2350         }
2351 
2352 /*/ ** */
2353 /*  * @brief  Exits from the Power down mode. */
2354 /*  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains */
2355 /*  *         the configuration information for ETHERNET module */
2356 /*  * @retval None. */
2357 /*  * / */
2358 /*void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth) */
2359 /*{ */
2360 /*  / * clear wake up sources * / */
2361 /*  CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | ETH_MACPCSR_RWKPFE); */
2362 /* */
2363 /*  if(READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != 0U) */
2364 /*  { */
2365 /*    / * Exit power down mode * / */
2366 /*    CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN); */
2367 /*  } */
2368 /* */
2369 /*  / * Disable PMT interrupt * / */
2370 /*  __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE); */
2371 /*} */
2372 /* */
2373 /*/ ** */
2374 /*  * @brief  Set the WakeUp filter. */
2375 /*  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains */
2376 /*  *         the configuration information for ETHERNET module */
2377 /*  * @param  pFilter: pointer to filter registers values */
2378 /*  * @param  Count: number of filter registers, must be from 1 to 8. */
2379 /*  * @retval None. */
2380 /*  * / */
2381 /*HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count) */
2382 /*{ */
2383 /*  uint32_t regindex; */
2384 /* */
2385 /*  if(pFilter == NULL) */
2386 /*  { */
2387 /*    return HAL_ERROR; */
2388 /*  } */
2389 /* */
2390 /*  / * Reset Filter Pointer * / */
2391 /*  SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST); */
2392 /* */
2393 /*  / * Wake up packet filter config * / */
2394 /*  for(regindex = 0; regindex < Count; regindex++) */
2395 /*  { */
2396 /*    / * Write filter regs * / */
2397 /*    WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]); */
2398 /*  } */
2399 /* */
2400 /*  return HAL_OK; */
2401 /*} */
2402 
2403 /**
2404  * @}
2405  */
2406 
2407 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2408  *  @brief   ETH State and Errors functions
2409  *
2410  * @verbatim
2411  * ==============================================================================
2412  ##### Peripheral State and Errors functions #####
2413  #####==============================================================================
2414  #####[..]
2415  #####This subsection provides a set of functions allowing to return the State of
2416  #####ETH communication process, return Peripheral Errors occurred during communication
2417  #####process
2418  #####
2419  #####
2420  #####@endverbatim
2421  * @{
2422  */
2423 
2424 /**
2425  * @brief  Returns the ETH state.
2426  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2427  *         the configuration information for ETHERNET module
2428  * @retval HAL state
2429  */
HAL_ETH_GetState(ETH_HandleTypeDef * heth)2430         HAL_ETH_StateTypeDef HAL_ETH_GetState( ETH_HandleTypeDef * heth )
2431         {
2432             HAL_ETH_StateTypeDef ret;
2433             HAL_ETH_StateTypeDef gstate = heth->gState;
2434             HAL_ETH_StateTypeDef rxstate = heth->RxState;
2435 
2436             ret = gstate;
2437             ret |= rxstate;
2438             return ret;
2439         }
2440 
2441 /**
2442  * @brief  Returns the ETH error code
2443  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2444  *         the configuration information for ETHERNET module
2445  * @retval ETH Error Code
2446  */
HAL_ETH_GetError(ETH_HandleTypeDef * heth)2447         uint32_t HAL_ETH_GetError( ETH_HandleTypeDef * heth )
2448         {
2449             return heth->ErrorCode;
2450         }
2451 
2452 /**
2453  * @brief  Returns the ETH DMA error code
2454  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2455  *         the configuration information for ETHERNET module
2456  * @retval ETH DMA Error Code
2457  */
HAL_ETH_GetDMAError(ETH_HandleTypeDef * heth)2458         uint32_t HAL_ETH_GetDMAError( ETH_HandleTypeDef * heth )
2459         {
2460             return heth->DMAErrorCode;
2461         }
2462 
2463 /**
2464  * @brief  Returns the ETH MAC error code
2465  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2466  *         the configuration information for ETHERNET module
2467  * @retval ETH MAC Error Code
2468  */
HAL_ETH_GetMACError(ETH_HandleTypeDef * heth)2469         uint32_t HAL_ETH_GetMACError( ETH_HandleTypeDef * heth )
2470         {
2471             return heth->MACErrorCode;
2472         }
2473 
2474 /**
2475  * @brief  Returns the ETH MAC WakeUp event source
2476  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2477  *         the configuration information for ETHERNET module
2478  * @retval ETH MAC WakeUp event source
2479  */
HAL_ETH_GetMACWakeUpSource(ETH_HandleTypeDef * heth)2480         uint32_t HAL_ETH_GetMACWakeUpSource( ETH_HandleTypeDef * heth )
2481         {
2482             return heth->MACWakeUpEvent;
2483         }
2484 
2485 /**
2486  * @}
2487  */
2488 
2489 /**
2490  * @}
2491  */
2492 
2493 /** @addtogroup ETH_Private_Functions   ETH Private Functions
2494  * @{
2495  */
2496 
ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2497         static void ETH_SetMACConfig( ETH_HandleTypeDef * heth,
2498                                       ETH_MACConfigTypeDef * macconf )
2499         {
2500             uint32_t macregval;
2501 
2502             /*------------------------ MACCR Configuration --------------------*/
2503             macregval = ( macconf->InterPacketGapVal |
2504                           macconf->SourceAddrControl |
2505                           ( ( uint32_t ) macconf->ChecksumOffload << 27 ) |
2506                           ( ( uint32_t ) macconf->GiantPacketSizeLimitControl << 23 ) |
2507                           ( ( uint32_t ) macconf->Support2KPacket << 22 ) |
2508                           ( ( uint32_t ) macconf->CRCStripTypePacket << 21 ) |
2509                           ( ( uint32_t ) macconf->AutomaticPadCRCStrip << 20 ) |
2510                           ( ( uint32_t ) ( ( macconf->Watchdog == DISABLE ) ? 1U : 0U ) << 19 ) |
2511                           ( ( uint32_t ) ( ( macconf->Jabber == DISABLE ) ? 1U : 0U ) << 17 ) |
2512                           ( ( uint32_t ) macconf->JumboPacket << 16 ) |
2513                           macconf->Speed |
2514                           macconf->DuplexMode |
2515                           ( ( uint32_t ) macconf->LoopbackMode << 12 ) |
2516                           ( ( uint32_t ) macconf->CarrierSenseBeforeTransmit << 11 ) |
2517                           ( ( uint32_t ) ( ( macconf->ReceiveOwn == DISABLE ) ? 1U : 0U ) << 10 ) |
2518                           ( ( uint32_t ) macconf->CarrierSenseDuringTransmit << 9 ) |
2519                           ( ( uint32_t ) ( ( macconf->RetryTransmission == DISABLE ) ? 1U : 0U ) << 8 ) |
2520                           macconf->BackOffLimit |
2521                           ( ( uint32_t ) macconf->DeferralCheck << 4 ) |
2522                           macconf->PreambleLength );
2523 
2524             /* Write to MACCR */
2525             MODIFY_REG( heth->Instance->MACCR, ETH_MACCR_MASK, macregval );
2526 
2527             /*------------------------ MACECR Configuration --------------------*/
2528             macregval = ( ( macconf->ExtendedInterPacketGapVal << 25 ) |
2529                           ( ( uint32_t ) macconf->ExtendedInterPacketGap << 24 ) |
2530                           ( ( uint32_t ) macconf->UnicastSlowProtocolPacketDetect << 18 ) |
2531                           ( ( uint32_t ) macconf->SlowProtocolDetect << 17 ) |
2532                           ( ( uint32_t ) ( ( macconf->CRCCheckingRxPackets == DISABLE ) ? 1U : 0U ) << 16 ) |
2533                           macconf->GiantPacketSizeLimit );
2534 
2535             /* Write to MACECR */
2536             MODIFY_REG( heth->Instance->MACECR, ETH_MACECR_MASK, macregval );
2537 
2538             /*------------------------ MACWTR Configuration --------------------*/
2539             macregval = ( ( ( uint32_t ) macconf->ProgrammableWatchdog << 8 ) |
2540                           macconf->WatchdogTimeout );
2541 
2542             /* Write to MACWTR */
2543             MODIFY_REG( heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval );
2544 
2545             /*------------------------ MACTFCR Configuration --------------------*/
2546             macregval = ( ( ( uint32_t ) macconf->TransmitFlowControl << 1 ) |
2547                           macconf->PauseLowThreshold |
2548                           ( ( uint32_t ) ( ( macconf->ZeroQuantaPause == DISABLE ) ? 1U : 0U ) << 7 ) |
2549                           ( macconf->PauseTime << 16 ) );
2550 
2551             /* Write to MACTFCR */
2552             MODIFY_REG( heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval );
2553 
2554             /*------------------------ MACRFCR Configuration --------------------*/
2555             macregval = ( ( uint32_t ) macconf->ReceiveFlowControl |
2556                           ( ( uint32_t ) macconf->UnicastPausePacketDetect << 1 ) );
2557 
2558             /* Write to MACRFCR */
2559             MODIFY_REG( heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval );
2560 
2561             /*------------------------ MTLTQOMR Configuration --------------------*/
2562             /* Write to MTLTQOMR */
2563             MODIFY_REG( heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode );
2564 
2565             /*------------------------ MTLRQOMR Configuration --------------------*/
2566             macregval = ( macconf->ReceiveQueueMode |
2567                           ( ( uint32_t ) ( ( macconf->DropTCPIPChecksumErrorPacket == DISABLE ) ? 1U : 0U ) << 6 ) |
2568                           ( ( uint32_t ) macconf->ForwardRxErrorPacket << 4 ) |
2569                           ( ( uint32_t ) macconf->ForwardRxUndersizedGoodPacket << 3 ) );
2570 
2571             /* Write to MTLRQOMR */
2572             MODIFY_REG( heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval );
2573         }
2574 
ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2575         static void ETH_SetDMAConfig( ETH_HandleTypeDef * heth,
2576                                       ETH_DMAConfigTypeDef * dmaconf )
2577         {
2578             uint32_t dmaregval;
2579 
2580             /*------------------------ DMAMR Configuration --------------------*/
2581             MODIFY_REG( heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration );
2582 
2583             /*------------------------ DMASBMR Configuration --------------------*/
2584             dmaregval = ( ( ( uint32_t ) dmaconf->AddressAlignedBeats << 12 ) |
2585                           dmaconf->BurstMode |
2586                           ( ( uint32_t ) dmaconf->RebuildINCRxBurst << 15 ) );
2587 
2588             MODIFY_REG( heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval );
2589 
2590             /*------------------------ DMACCR Configuration --------------------*/
2591             dmaregval = ( ( ( uint32_t ) dmaconf->PBLx8Mode << 16 ) |
2592                           dmaconf->MaximumSegmentSize );
2593 
2594             MODIFY_REG( heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval );
2595 
2596             /*------------------------ DMACTCR Configuration --------------------*/
2597             dmaregval = ( dmaconf->TxDMABurstLength |
2598                           ( ( uint32_t ) dmaconf->SecondPacketOperate << 4 ) |
2599                           ( ( uint32_t ) dmaconf->TCPSegmentation << 12 ) );
2600 
2601             MODIFY_REG( heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval );
2602 
2603             /*------------------------ DMACRCR Configuration --------------------*/
2604             dmaregval = ( ( ( uint32_t ) dmaconf->FlushRxPacket << 31 ) |
2605                           dmaconf->RxDMABurstLength );
2606 
2607             /* Write to DMACRCR */
2608             MODIFY_REG( heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval );
2609         }
2610 
2611 /**
2612  * @brief  Configures Ethernet MAC and DMA with default parameters.
2613  *         called by HAL_ETH_Init() API.
2614  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2615  *         the configuration information for ETHERNET module
2616  * @retval HAL status
2617  */
ETH_MACDMAConfig(ETH_HandleTypeDef * heth)2618         static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth )
2619         {
2620             ETH_MACConfigTypeDef macDefaultConf;
2621             ETH_DMAConfigTypeDef dmaDefaultConf;
2622 
2623             /*--------------- ETHERNET MAC registers default Configuration --------------*/
2624             macDefaultConf.AutomaticPadCRCStrip = ENABLE;
2625             macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2626             macDefaultConf.CarrierSenseBeforeTransmit = DISABLE;
2627             macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2628             macDefaultConf.ChecksumOffload = ENABLE;
2629             macDefaultConf.CRCCheckingRxPackets = ENABLE;
2630             macDefaultConf.CRCStripTypePacket = ENABLE;
2631             macDefaultConf.DeferralCheck = DISABLE;
2632             macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE;
2633             macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2634             macDefaultConf.ExtendedInterPacketGap = DISABLE;
2635             macDefaultConf.ExtendedInterPacketGapVal = 0x0;
2636             macDefaultConf.ForwardRxErrorPacket = DISABLE;
2637             macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE;
2638             macDefaultConf.GiantPacketSizeLimit = 0x618;
2639             macDefaultConf.GiantPacketSizeLimitControl = DISABLE;
2640             macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT;
2641             macDefaultConf.Jabber = ENABLE;
2642             macDefaultConf.JumboPacket = DISABLE;
2643             macDefaultConf.LoopbackMode = DISABLE;
2644             macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4;
2645             macDefaultConf.PauseTime = 0x0;
2646             macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7;
2647             macDefaultConf.ProgrammableWatchdog = DISABLE;
2648             macDefaultConf.ReceiveFlowControl = DISABLE;
2649             macDefaultConf.ReceiveOwn = ENABLE;
2650             macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD;
2651             macDefaultConf.RetryTransmission = ENABLE;
2652             macDefaultConf.SlowProtocolDetect = DISABLE;
2653             macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0;
2654             macDefaultConf.Speed = ETH_SPEED_100M;
2655             macDefaultConf.Support2KPacket = DISABLE;
2656             macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD;
2657             macDefaultConf.TransmitFlowControl = DISABLE;
2658             macDefaultConf.UnicastPausePacketDetect = DISABLE;
2659             macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE;
2660             macDefaultConf.Watchdog = ENABLE;
2661             macDefaultConf.WatchdogTimeout = ETH_MACWTR_WTO_2KB;
2662             macDefaultConf.ZeroQuantaPause = ENABLE;
2663 
2664             /* MAC default configuration */
2665             ETH_SetMACConfig( heth, &macDefaultConf );
2666 
2667             /*--------------- ETHERNET DMA registers default Configuration --------------*/
2668             dmaDefaultConf.AddressAlignedBeats = ENABLE;
2669             dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2670             dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1;
2671             dmaDefaultConf.FlushRxPacket = DISABLE;
2672             dmaDefaultConf.PBLx8Mode = DISABLE;
2673             dmaDefaultConf.RebuildINCRxBurst = DISABLE;
2674             dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2675             dmaDefaultConf.SecondPacketOperate = DISABLE;
2676             dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2677             dmaDefaultConf.TCPSegmentation = DISABLE;
2678             dmaDefaultConf.MaximumSegmentSize = 536;
2679 
2680             /* DMA default configuration */
2681             ETH_SetDMAConfig( heth, &dmaDefaultConf );
2682         }
2683 
2684 /**
2685  * @brief  Configures the Clock range of SMI interface.
2686  *         called by HAL_ETH_Init() API.
2687  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2688  *         the configuration information for ETHERNET module
2689  * @retval None
2690  */
ETH_MAC_MDIO_ClkConfig(ETH_HandleTypeDef * heth)2691         static void ETH_MAC_MDIO_ClkConfig( ETH_HandleTypeDef * heth )
2692         {
2693             uint32_t tmpreg, hclk;
2694 
2695             /* Get the ETHERNET MACMDIOAR value */
2696             tmpreg = ( heth->Instance )->MACMDIOAR;
2697 
2698             /* Clear CSR Clock Range bits */
2699             tmpreg &= ~ETH_MACMDIOAR_CR;
2700 
2701             /* Get hclk frequency value */
2702             hclk = HAL_RCC_GetHCLKFreq();
2703 
2704             /* Set CR bits depending on hclk value */
2705             if( ( hclk >= 20000000U ) && ( hclk < 35000000U ) )
2706             {
2707                 /* CSR Clock Range between 20-35 MHz */
2708                 tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV16;
2709             }
2710             else if( ( hclk >= 35000000U ) && ( hclk < 60000000U ) )
2711             {
2712                 /* CSR Clock Range between 35-60 MHz */
2713                 tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV26;
2714             }
2715             else if( ( hclk >= 60000000U ) && ( hclk < 100000000U ) )
2716             {
2717                 /* CSR Clock Range between 60-100 MHz */
2718                 tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV42;
2719             }
2720             else if( ( hclk >= 100000000U ) && ( hclk < 150000000U ) )
2721             {
2722                 /* CSR Clock Range between 100-150 MHz */
2723                 tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV62;
2724             }
2725             else /* (hclk >= 150000000)&&(hclk <= 200000000) */
2726             {
2727                 /* CSR Clock Range between 150-200 MHz */
2728                 tmpreg |= ( uint32_t ) ETH_MACMDIOAR_CR_DIV102;
2729             }
2730 
2731             /* Configure the CSR Clock Range */
2732             ( heth->Instance )->MACMDIOAR = ( uint32_t ) tmpreg;
2733         }
2734 
2735 /**
2736  * @brief  Initializes the DMA Tx descriptors.
2737  *         called by HAL_ETH_Init() API.
2738  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2739  *         the configuration information for ETHERNET module
2740  * @retval None
2741  */
ETH_DMATxDescListInit(ETH_HandleTypeDef * heth)2742         static void ETH_DMATxDescListInit( ETH_HandleTypeDef * heth )
2743         {
2744             ETH_DMADescTypeDef * dmatxdesc;
2745             uint32_t i;
2746 
2747             /* Fill each DMATxDesc descriptor with the right values */
2748             for( i = 0; i < ( uint32_t ) ETH_TX_DESC_CNT; i++ )
2749             {
2750                 dmatxdesc = heth->Init.TxDesc + i;
2751 
2752                 WRITE_REG( dmatxdesc->DESC0, 0x0 );
2753                 WRITE_REG( dmatxdesc->DESC1, 0x0 );
2754                 WRITE_REG( dmatxdesc->DESC2, 0x0 );
2755                 WRITE_REG( dmatxdesc->DESC3, 0x0 );
2756 
2757                 WRITE_REG( heth->TxDescList.TxDesc[ i ], ( uint32_t ) dmatxdesc );
2758             }
2759 
2760             heth->TxDescList.CurTxDesc = 0;
2761             heth->TxDescList.TailTxDesc = 0;
2762 
2763             /* Set Transmit Descriptor Ring Length */
2764             WRITE_REG( heth->Instance->DMACTDRLR, ( ETH_TX_DESC_CNT - 1 ) );
2765 
2766             /* Set Transmit Descriptor List Address */
2767             /* Channel Tx descriptor list address register (ETH_DMACTXDLAR)). */
2768             WRITE_REG( heth->Instance->DMACTDLAR, ( uint32_t ) heth->Init.TxDesc );
2769 
2770             /* Set Transmit Descriptor Tail pointer */
2771             WRITE_REG( heth->Instance->DMACTDTPR, ( uint32_t ) heth->Init.TxDesc );
2772         }
2773 
2774 /**
2775  * @brief  Initializes the DMA Rx descriptors in chain mode.
2776  *         called by HAL_ETH_Init() API.
2777  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2778  *         the configuration information for ETHERNET module
2779  * @retval None
2780  */
ETH_DMARxDescListInit(ETH_HandleTypeDef * heth)2781         static void ETH_DMARxDescListInit( ETH_HandleTypeDef * heth )
2782         {
2783             ETH_DMADescTypeDef * dmarxdesc;
2784             uint32_t i;
2785 
2786             for( i = 0; i < ( uint32_t ) ETH_RX_DESC_CNT; i++ )
2787             {
2788                 dmarxdesc = heth->Init.RxDesc + i;
2789 
2790                 WRITE_REG( dmarxdesc->DESC0, 0x0 );
2791                 WRITE_REG( dmarxdesc->DESC1, 0x0 );
2792                 WRITE_REG( dmarxdesc->DESC2, 0x0 );
2793                 WRITE_REG( dmarxdesc->DESC3, 0x0 );
2794                 WRITE_REG( dmarxdesc->BackupAddr0, 0x0 );
2795                 WRITE_REG( dmarxdesc->BackupAddr1, 0x0 );
2796 
2797                 /* Set Rx descritors adresses */
2798                 WRITE_REG( heth->RxDescList.RxDesc[ i ], ( uint32_t ) dmarxdesc );
2799             }
2800 
2801             WRITE_REG( heth->RxDescList.CurRxDesc, 0 );
2802             WRITE_REG( heth->RxDescList.FirstAppDesc, 0 );
2803             WRITE_REG( heth->RxDescList.AppDescNbr, 0 );
2804             WRITE_REG( heth->RxDescList.ItMode, 0 );
2805             WRITE_REG( heth->RxDescList.AppContextDesc, 0 );
2806 
2807             /* Set Receive Descriptor Ring Length */
2808             WRITE_REG( heth->Instance->DMACRDRLR, ( uint32_t ) ( ETH_RX_DESC_CNT - 1 ) );
2809 
2810             /* Set Receive Descriptor List Address */
2811             /* Channel Rx descriptor list address register (ETH_DMACRXDLAR)). */
2812             WRITE_REG( heth->Instance->DMACRDLAR, ( uint32_t ) heth->Init.RxDesc );
2813 
2814             /* Set Receive Descriptor Tail pointer Address */
2815             WRITE_REG( heth->Instance->DMACRDTPR, ( ( uint32_t ) ( heth->Init.RxDesc + ( uint32_t ) ( ETH_RX_DESC_CNT - 1 ) ) ) );
2816         }
2817 
ETH_Clear_Tx_Descriptors(ETH_HandleTypeDef * heth)2818         void ETH_Clear_Tx_Descriptors( ETH_HandleTypeDef * heth )
2819         {
2820             uint32_t ulTailTxDesc = heth->TxDescList.TailTxDesc;
2821 
2822             while( ( uxSemaphoreGetCount( xTXDescriptorSemaphore ) ) != ETH_TX_DESC_CNT )
2823             {
2824                 ETH_DMADescTypeDef * xDMATxDescriptor = ( ETH_DMADescTypeDef * ) heth->TxDescList.TxDesc[ ulTailTxDesc ];
2825 
2826                 if( ( xDMATxDescriptor->DESC3 & ETH_DMATXNDESCRF_OWN ) != 0 )
2827                 {
2828                     /* No buffer is assigned or DMA still OWNs this descriptor. */
2829                     break;
2830                 }
2831 
2832                 #if ( ipconfigZERO_COPY_TX_DRIVER != 0 )
2833                     {
2834                         NetworkBufferDescriptor_t * pxNetworkBuffer;
2835                         uint8_t * ucPayLoad;
2836 
2837                         ucPayLoad = ( uint8_t * ) xDMATxDescriptor->DESC0;
2838 
2839                         if( ucPayLoad == NULL )
2840                         {
2841                             /* No buffer is assigned or DMA still OWNs this descriptor. */
2842                             break;
2843                         }
2844 
2845                         pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
2846 
2847                         if( pxNetworkBuffer != NULL )
2848                         {
2849                             vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
2850                         }
2851                     }
2852                 #endif /* if ( ipconfigZERO_COPY_TX_DRIVER != 0 ) */
2853 
2854                 xDMATxDescriptor->DESC0 = ( uint32_t ) 0u;
2855 
2856                 INCR_TX_DESC_INDEX( ulTailTxDesc, 1U );
2857                 heth->TxDescList.TailTxDesc = ulTailTxDesc;
2858 
2859                 __DSB();
2860 
2861                 xSemaphoreGive( xTXDescriptorSemaphore );
2862             }
2863         }
2864 
2865 /**
2866  * @brief  Prepare Tx DMA descriptor before transmission.
2867  *         called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
2868  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2869  *         the configuration information for ETHERNET module
2870  * @param  pTxConfig: Tx packet configuration
2871  * @param  ItMode: Enable or disable Tx EOT interrept
2872  * @retval Status
2873  */
ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef * heth,ETH_TxPacketConfig * pTxConfig,uint32_t ItMode)2874         static uint32_t ETH_Prepare_Tx_Descriptors( ETH_HandleTypeDef * heth,
2875                                                     ETH_TxPacketConfig * pTxConfig,
2876                                                     uint32_t ItMode )
2877         {
2878             ETH_TxDescListTypeDef * dmatxdesclist = &heth->TxDescList;
2879             uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
2880             uint32_t DESC3;
2881             ETH_DMADescTypeDef * dmatxdesc = ( ETH_DMADescTypeDef * ) dmatxdesclist->TxDesc[ firstdescidx ];
2882             ETH_BufferTypeDef * txbuffer = pTxConfig->TxBuffer;
2883 
2884             /* FreeRTOS+TCP doesn't support linked buffers. */
2885             txbuffer->next = NULL;
2886             DESC3 = READ_REG( dmatxdesc->DESC3 );
2887 
2888             /* Current TX Descriptor Owned by DMA: cannot be used by the application  */
2889             if( READ_BIT( DESC3, ETH_DMATXNDESCWBF_OWN ) != 0U )
2890             {
2891                 /* Should not get here because TX descriptors are protected by a counting semaphore. */
2892                 return HAL_ETH_ERROR_BUSY;
2893             }
2894 
2895             /***************************************************************************/
2896             /*****************    Normal descriptors configuration     *****************/
2897             /***************************************************************************/
2898 
2899             /* Set header or buffer 1 address */
2900             WRITE_REG( dmatxdesc->DESC0, ( uint32_t ) txbuffer->buffer );
2901             /* Set header or buffer 1 Length */
2902             MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len );
2903 
2904             WRITE_REG( dmatxdesc->DESC1, 0x0 );
2905             /* Set buffer 2 Length to zero */
2906             MODIFY_REG( dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U );
2907 
2908             MODIFY_REG( DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length );
2909 
2910             if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM ) != 0U )
2911             {
2912                 MODIFY_REG( DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl );
2913             }
2914 
2915             if( READ_BIT( pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD ) != 0U )
2916             {
2917                 MODIFY_REG( DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl );
2918             }
2919 
2920             /* Mark it as First and the last Descriptor */
2921             SET_BIT( DESC3, ETH_DMATXNDESCRF_FD | ETH_DMATXNDESCRF_LD );
2922 
2923             /* Mark it as NORMAL descriptor */
2924             CLEAR_BIT( DESC3, ETH_DMATXNDESCRF_CTXT );
2925 
2926             /* set OWN bit of FIRST descriptor */
2927             SET_BIT( DESC3, ETH_DMATXNDESCRF_OWN );
2928 
2929             if( ItMode != ( ( uint32_t ) RESET ) )
2930             {
2931                 /* Set Interrupt on competition bit */
2932                 SET_BIT( dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC );
2933             }
2934             else
2935             {
2936                 /* Clear Interrupt on competition bit */
2937                 CLEAR_BIT( dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC );
2938             }
2939 
2940             WRITE_REG( dmatxdesc->DESC3, DESC3 );
2941 
2942             /* Read back the value. */
2943             if( READ_REG( dmatxdesc->DESC3 ) )
2944             {
2945             }
2946 
2947             __DSB();
2948 
2949             /* Return function status */
2950             return HAL_ETH_ERROR_NONE;
2951         }
2952 
2953         #if ( USE_HAL_ETH_REGISTER_CALLBACKS == 1 )
ETH_InitCallbacksToDefault(ETH_HandleTypeDef * heth)2954             static void ETH_InitCallbacksToDefault( ETH_HandleTypeDef * heth )
2955             {
2956                 /* Init the ETH Callback settings */
2957                 heth->TxCpltCallback = HAL_ETH_TxCpltCallback;     /* Legacy weak TxCpltCallback   */
2958                 heth->RxCpltCallback = HAL_ETH_RxCpltCallback;     /* Legacy weak RxCpltCallback   */
2959                 heth->DMAErrorCallback = HAL_ETH_DMAErrorCallback; /* Legacy weak DMAErrorCallback */
2960                 heth->MACErrorCallback = HAL_ETH_MACErrorCallback; /* Legacy weak MACErrorCallback */
2961                 heth->PMTCallback = HAL_ETH_PMTCallback;           /* Legacy weak PMTCallback      */
2962                 heth->EEECallback = HAL_ETH_EEECallback;           /* Legacy weak EEECallback      */
2963                 heth->WakeUpCallback = HAL_ETH_WakeUpCallback;     /* Legacy weak WakeUpCallback   */
2964             }
2965         #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2966 
2967 /**
2968  * @}
2969  */
2970 
2971 /**
2972  * @}
2973  */
2974 
2975     #endif /* ETH */
2976 
2977 #endif /* HAL_ETH_MODULE_ENABLED */
2978 
2979 /**
2980  * @}
2981  */
2982 
2983 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2984