1 /**
2   ******************************************************************************
3   * @file    stm32f1xx_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 de-initialization 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       (#)Declare a ETH_HandleTypeDef handle structure, for example:
19          ETH_HandleTypeDef  heth;
20 
21       (#)Fill parameters of Init structure in heth handle
22 
23       (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
24 
25       (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
26           (##) Enable the Ethernet interface clock using
27                (+++) __HAL_RCC_ETHMAC_CLK_ENABLE();
28                (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE();
29                (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE();
30 
31           (##) Initialize the related GPIO clocks
32           (##) Configure Ethernet pin-out
33           (##) Configure Ethernet NVIC interrupt (IT mode)
34 
35       (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:
36           (##) HAL_ETH_DMATxDescListInit(); for Transmission process
37           (##) HAL_ETH_DMARxDescListInit(); for Reception process
38 
39       (#)Enable MAC and DMA transmission and reception:
40           (##) HAL_ETH_Start();
41 
42       (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer
43          the frame to MAC TX FIFO:
44          (##) HAL_ETH_TransmitFrame();
45 
46       (#)Poll for a received frame in ETH RX DMA Descriptors and get received
47          frame parameters
48          (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)
49 
50       (#) Get a received frame when an ETH RX interrupt occurs:
51          (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)
52 
53       (#) Communicate with external PHY device:
54          (##) Read a specific register from the PHY
55               HAL_ETH_ReadPHYRegister();
56          (##) Write data to a specific RHY register:
57               HAL_ETH_WritePHYRegister();
58 
59       (#) Configure the Ethernet MAC after ETH peripheral initialization
60           HAL_ETH_ConfigMAC(); all MAC parameters should be filled.
61 
62       (#) Configure the Ethernet DMA after ETH peripheral initialization
63           HAL_ETH_ConfigDMA(); all DMA parameters should be filled.
64 
65       -@- The PTP protocol and the DMA descriptors ring mode are not supported
66           in this driver
67 *** Callback registration ***
68   =============================================
69 
70   The compilation define  USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
71   allows the user to configure dynamically the driver callbacks.
72   Use Function @ref HAL_ETH_RegisterCallback() to register an interrupt callback.
73 
74   Function @ref HAL_ETH_RegisterCallback() allows to register following callbacks:
75     (+) TxCpltCallback   : Tx Complete Callback.
76     (+) RxCpltCallback   : Rx Complete Callback.
77     (+) DMAErrorCallback : DMA Error Callback.
78     (+) MspInitCallback  : MspInit Callback.
79     (+) MspDeInitCallback: MspDeInit Callback.
80 
81   This function takes as parameters the HAL peripheral handle, the Callback ID
82   and a pointer to the user callback function.
83 
84   Use function @ref HAL_ETH_UnRegisterCallback() to reset a callback to the default
85   weak function.
86   @ref HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
87   and the Callback ID.
88   This function allows to reset following callbacks:
89     (+) TxCpltCallback   : Tx Complete Callback.
90     (+) RxCpltCallback   : Rx Complete Callback.
91     (+) DMAErrorCallback : DMA Error Callback.
92     (+) MspInitCallback  : MspInit Callback.
93     (+) MspDeInitCallback: MspDeInit Callback.
94 
95   By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
96   all callbacks are set to the corresponding weak functions:
97   examples @ref HAL_ETH_TxCpltCallback(), @ref HAL_ETH_RxCpltCallback().
98   Exception done for MspInit and MspDeInit functions that are
99   reset to the legacy weak function in the HAL_ETH_Init/ @ref HAL_ETH_DeInit only when
100   these callbacks are null (not registered beforehand).
101   if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ @ref HAL_ETH_DeInit
102   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
103 
104   Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
105   Exception done MspInit/MspDeInit that can be registered/unregistered
106   in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
107   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
108   In that case first register the MspInit/MspDeInit user callbacks
109   using @ref HAL_ETH_RegisterCallback() before calling @ref HAL_ETH_DeInit
110   or HAL_ETH_Init function.
111 
112   When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
113   not defined, the callback registration feature is not available and all callbacks
114   are set to the corresponding weak functions.
115 
116   @endverbatim
117   ******************************************************************************
118   * @attention
119   *
120   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
121   * All rights reserved.</center></h2>
122   *
123   * This software component is licensed by ST under BSD 3-Clause license,
124   * the "License"; You may not use this file except in compliance with the
125   * License. You may obtain a copy of the License at:
126   *                        opensource.org/licenses/BSD-3-Clause
127   *
128   ******************************************************************************
129   */
130 
131 /* Includes ------------------------------------------------------------------*/
132 #include "stm32f1xx_hal.h"
133 
134 /** @addtogroup STM32F1xx_HAL_Driver
135   * @{
136   */
137 
138 /** @defgroup ETH ETH
139   * @brief ETH HAL module driver
140   * @{
141   */
142 
143 #ifdef HAL_ETH_MODULE_ENABLED
144 
145 #if defined (ETH)
146 
147 /* Private typedef -----------------------------------------------------------*/
148 /* Private define ------------------------------------------------------------*/
149 /** @defgroup ETH_Private_Constants ETH Private Constants
150   * @{
151   */
152 #define ETH_TIMEOUT_SWRESET               500U
153 #define ETH_TIMEOUT_LINKED_STATE          5000U
154 #define ETH_TIMEOUT_AUTONEGO_COMPLETED    5000U
155 
156 /**
157   * @}
158   */
159 /* Private macro -------------------------------------------------------------*/
160 /* Private variables ---------------------------------------------------------*/
161 /* Private function prototypes -----------------------------------------------*/
162 /** @defgroup ETH_Private_Functions ETH Private Functions
163   * @{
164   */
165 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err);
166 static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
167 static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth);
168 static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth);
169 static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth);
170 static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth);
171 static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth);
172 static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth);
173 static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth);
174 static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth);
175 static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
176 static void ETH_Delay(uint32_t mdelay);
177 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
178 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
179 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
180 
181 /**
182   * @}
183   */
184 /* Private functions ---------------------------------------------------------*/
185 
186 /** @defgroup ETH_Exported_Functions ETH Exported Functions
187   * @{
188   */
189 
190 /** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions
191   *  @brief   Initialization and Configuration functions
192   *
193   @verbatim
194   ===============================================================================
195             ##### Initialization and de-initialization functions #####
196   ===============================================================================
197   [..]  This section provides functions allowing to:
198       (+) Initialize and configure the Ethernet peripheral
199       (+) De-initialize the Ethernet peripheral
200 
201   @endverbatim
202   * @{
203   */
204 
205 /**
206   * @brief  Initializes the Ethernet MAC and DMA according to default
207   *         parameters.
208   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
209   *         the configuration information for ETHERNET module
210   * @retval HAL status
211   */
HAL_ETH_Init(ETH_HandleTypeDef * heth)212 HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
213 {
214   uint32_t tmpreg1 = 0U, phyreg = 0U;
215   uint32_t hclk = 60000000U;
216   uint32_t tickstart = 0U;
217   uint32_t err = ETH_SUCCESS;
218 
219   /* Check the ETH peripheral state */
220   if (heth == NULL)
221   {
222     return HAL_ERROR;
223   }
224 
225   /* Check parameters */
226   assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
227   assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
228   assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
229   assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
230 
231   if (heth->State == HAL_ETH_STATE_RESET)
232   {
233     /* Allocate lock resource and initialize it */
234     heth->Lock = HAL_UNLOCKED;
235 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
236     ETH_InitCallbacksToDefault(heth);
237 
238     if (heth->MspInitCallback == NULL)
239     {
240       /* Init the low level hardware : GPIO, CLOCK, NVIC. */
241       heth->MspInitCallback = HAL_ETH_MspInit;
242     }
243     heth->MspInitCallback(heth);
244 
245 #else
246     /* Init the low level hardware : GPIO, CLOCK, NVIC. */
247     HAL_ETH_MspInit(heth);
248 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
249   }
250 
251   /* Select MII or RMII Mode*/
252   AFIO->MAPR &= ~(AFIO_MAPR_MII_RMII_SEL);
253   AFIO->MAPR |= (uint32_t)heth->Init.MediaInterface;
254 
255   /* Ethernet Software reset */
256   /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
257   /* After reset all the registers holds their respective reset values */
258   (heth->Instance)->DMABMR |= ETH_DMABMR_SR;
259 
260   /* Get tick */
261   tickstart = HAL_GetTick();
262 
263   /* Wait for software reset */
264   while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
265   {
266     /* Check for the Timeout */
267     if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_SWRESET)
268     {
269       heth->State = HAL_ETH_STATE_TIMEOUT;
270 
271       /* Process Unlocked */
272       __HAL_UNLOCK(heth);
273 
274       /* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are
275          not available, please check your external PHY or the IO configuration */
276       return HAL_TIMEOUT;
277     }
278   }
279 
280   /*-------------------------------- MAC Initialization ----------------------*/
281   /* Get the ETHERNET MACMIIAR value */
282   tmpreg1 = (heth->Instance)->MACMIIAR;
283   /* Clear CSR Clock Range CR[2:0] bits */
284   tmpreg1 &= ETH_MACMIIAR_CR_MASK;
285 
286   /* Get hclk frequency value */
287   hclk = HAL_RCC_GetHCLKFreq();
288 
289   /* Set CR bits depending on hclk value */
290   if ((hclk >= 20000000U) && (hclk < 35000000U))
291   {
292     /* CSR Clock Range between 20-35 MHz */
293     tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV16;
294   }
295   else if ((hclk >= 35000000U) && (hclk < 60000000U))
296   {
297     /* CSR Clock Range between 35-60 MHz */
298     tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV26;
299   }
300   else
301   {
302     /* CSR Clock Range between 60-72 MHz */
303     tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV42;
304   }
305 
306   /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
307   (heth->Instance)->MACMIIAR = (uint32_t)tmpreg1;
308 
309   /*-------------------- PHY initialization and configuration ----------------*/
310   /* Put the PHY in reset mode */
311   if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK)
312   {
313     /* In case of write timeout */
314     err = ETH_ERROR;
315 
316     /* Config MAC and DMA */
317     ETH_MACDMAConfig(heth, err);
318 
319     /* Set the ETH peripheral state to READY */
320     heth->State = HAL_ETH_STATE_READY;
321 
322     /* Return HAL_ERROR */
323     return HAL_ERROR;
324   }
325 
326   /* Delay to assure PHY reset */
327   HAL_Delay(PHY_RESET_DELAY);
328 
329   if ((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
330   {
331     /* Get tick */
332     tickstart = HAL_GetTick();
333 
334     /* We wait for linked status */
335     do
336     {
337       HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
338 
339       /* Check for the Timeout */
340       if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_LINKED_STATE)
341       {
342         /* In case of write timeout */
343         err = ETH_ERROR;
344 
345         /* Config MAC and DMA */
346         ETH_MACDMAConfig(heth, err);
347 
348         heth->State = HAL_ETH_STATE_READY;
349 
350         /* Process Unlocked */
351         __HAL_UNLOCK(heth);
352 
353         return HAL_TIMEOUT;
354       }
355     }
356     while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));
357 
358 
359     /* Enable Auto-Negotiation */
360     if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK)
361     {
362       /* In case of write timeout */
363       err = ETH_ERROR;
364 
365       /* Config MAC and DMA */
366       ETH_MACDMAConfig(heth, err);
367 
368       /* Set the ETH peripheral state to READY */
369       heth->State = HAL_ETH_STATE_READY;
370 
371       /* Return HAL_ERROR */
372       return HAL_ERROR;
373     }
374 
375     /* Get tick */
376     tickstart = HAL_GetTick();
377 
378     /* Wait until the auto-negotiation will be completed */
379     do
380     {
381       HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
382 
383       /* Check for the Timeout */
384       if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_AUTONEGO_COMPLETED)
385       {
386         /* In case of write timeout */
387         err = ETH_ERROR;
388 
389         /* Config MAC and DMA */
390         ETH_MACDMAConfig(heth, err);
391 
392         heth->State = HAL_ETH_STATE_READY;
393 
394         /* Process Unlocked */
395         __HAL_UNLOCK(heth);
396 
397         return HAL_TIMEOUT;
398       }
399 
400     }
401     while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
402 
403     /* Read the result of the auto-negotiation */
404     if ((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK)
405     {
406       /* In case of write timeout */
407       err = ETH_ERROR;
408 
409       /* Config MAC and DMA */
410       ETH_MACDMAConfig(heth, err);
411 
412       /* Set the ETH peripheral state to READY */
413       heth->State = HAL_ETH_STATE_READY;
414 
415       /* Return HAL_ERROR */
416       return HAL_ERROR;
417     }
418 
419     /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
420     if ((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
421     {
422       /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
423       (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
424     }
425     else
426     {
427       /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
428       (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
429     }
430     /* Configure the MAC with the speed fixed by the auto-negotiation process */
431     if ((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS)
432     {
433       /* Set Ethernet speed to 10M following the auto-negotiation */
434       (heth->Init).Speed = ETH_SPEED_10M;
435     }
436     else
437     {
438       /* Set Ethernet speed to 100M following the auto-negotiation */
439       (heth->Init).Speed = ETH_SPEED_100M;
440     }
441   }
442   else /* AutoNegotiation Disable */
443   {
444     /* Check parameters */
445     assert_param(IS_ETH_SPEED(heth->Init.Speed));
446     assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
447 
448     /* Set MAC Speed and Duplex Mode */
449     if (HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) |
450                                                  (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK)
451     {
452       /* In case of write timeout */
453       err = ETH_ERROR;
454 
455       /* Config MAC and DMA */
456       ETH_MACDMAConfig(heth, err);
457 
458       /* Set the ETH peripheral state to READY */
459       heth->State = HAL_ETH_STATE_READY;
460 
461       /* Return HAL_ERROR */
462       return HAL_ERROR;
463     }
464 
465     /* Delay to assure PHY configuration */
466     HAL_Delay(PHY_CONFIG_DELAY);
467   }
468 
469   /* Config MAC and DMA */
470   ETH_MACDMAConfig(heth, err);
471 
472   /* Set ETH HAL State to Ready */
473   heth->State = HAL_ETH_STATE_READY;
474 
475   /* Return function status */
476   return HAL_OK;
477 }
478 
479 /**
480   * @brief  De-Initializes the ETH peripheral.
481   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
482   *         the configuration information for ETHERNET module
483   * @retval HAL status
484   */
HAL_ETH_DeInit(ETH_HandleTypeDef * heth)485 HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
486 {
487   /* Set the ETH peripheral state to BUSY */
488   heth->State = HAL_ETH_STATE_BUSY;
489 
490 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
491   if (heth->MspDeInitCallback == NULL)
492   {
493     heth->MspDeInitCallback = HAL_ETH_MspDeInit;
494   }
495   /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
496   heth->MspDeInitCallback(heth);
497 #else
498   /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
499   HAL_ETH_MspDeInit(heth);
500 #endif
501 
502   /* Set ETH HAL state to Disabled */
503   heth->State = HAL_ETH_STATE_RESET;
504 
505   /* Release Lock */
506   __HAL_UNLOCK(heth);
507 
508   /* Return function status */
509   return HAL_OK;
510 }
511 
512 /**
513   * @brief  Initializes the DMA Tx descriptors in chain mode.
514   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
515   *         the configuration information for ETHERNET module
516   * @param  DMATxDescTab: Pointer to the first Tx desc list
517   * @param  TxBuff: Pointer to the first TxBuffer list
518   * @param  TxBuffCount: Number of the used Tx desc in the list
519   * @retval HAL status
520   */
HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef * heth,ETH_DMADescTypeDef * DMATxDescTab,uint8_t * TxBuff,uint32_t TxBuffCount)521 HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount)
522 {
523   uint32_t i = 0U;
524   ETH_DMADescTypeDef *dmatxdesc;
525 
526   /* Process Locked */
527   __HAL_LOCK(heth);
528 
529   /* Set the ETH peripheral state to BUSY */
530   heth->State = HAL_ETH_STATE_BUSY;
531 
532   /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */
533   heth->TxDesc = DMATxDescTab;
534 
535   /* Fill each DMATxDesc descriptor with the right values */
536   for (i = 0U; i < TxBuffCount; i++)
537   {
538     /* Get the pointer on the ith member of the Tx Desc list */
539     dmatxdesc = DMATxDescTab + i;
540 
541     /* Set Second Address Chained bit */
542     dmatxdesc->Status = ETH_DMATXDESC_TCH;
543 
544     /* Set Buffer1 address pointer */
545     dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i * ETH_TX_BUF_SIZE]);
546 
547     if ((heth->Init).ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
548     {
549       /* Set the DMA Tx descriptors checksum insertion */
550       dmatxdesc->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
551     }
552 
553     /* Initialize the next descriptor with the Next Descriptor Polling Enable */
554     if (i < (TxBuffCount - 1U))
555     {
556       /* Set next descriptor address register with next descriptor base address */
557       dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + i + 1U);
558     }
559     else
560     {
561       /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
562       dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
563     }
564   }
565 
566   /* Set Transmit Descriptor List Address Register */
567   (heth->Instance)->DMATDLAR = (uint32_t) DMATxDescTab;
568 
569   /* Set ETH HAL State to Ready */
570   heth->State = HAL_ETH_STATE_READY;
571 
572   /* Process Unlocked */
573   __HAL_UNLOCK(heth);
574 
575   /* Return function status */
576   return HAL_OK;
577 }
578 
579 /**
580   * @brief  Initializes the DMA Rx descriptors in chain mode.
581   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
582   *         the configuration information for ETHERNET module
583   * @param  DMARxDescTab: Pointer to the first Rx desc list
584   * @param  RxBuff: Pointer to the first RxBuffer list
585   * @param  RxBuffCount: Number of the used Rx desc in the list
586   * @retval HAL status
587   */
HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef * heth,ETH_DMADescTypeDef * DMARxDescTab,uint8_t * RxBuff,uint32_t RxBuffCount)588 HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
589 {
590   uint32_t i = 0U;
591   ETH_DMADescTypeDef *DMARxDesc;
592 
593   /* Process Locked */
594   __HAL_LOCK(heth);
595 
596   /* Set the ETH peripheral state to BUSY */
597   heth->State = HAL_ETH_STATE_BUSY;
598 
599   /* Set the Ethernet RxDesc pointer with the first one of the DMARxDescTab list */
600   heth->RxDesc = DMARxDescTab;
601 
602   /* Fill each DMARxDesc descriptor with the right values */
603   for (i = 0U; i < RxBuffCount; i++)
604   {
605     /* Get the pointer on the ith member of the Rx Desc list */
606     DMARxDesc = DMARxDescTab + i;
607 
608     /* Set Own bit of the Rx descriptor Status */
609     DMARxDesc->Status = ETH_DMARXDESC_OWN;
610 
611     /* Set Buffer1 size and Second Address Chained bit */
612     DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
613 
614     /* Set Buffer1 address pointer */
615     DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_RX_BUF_SIZE]);
616 
617     if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
618     {
619       /* Enable Ethernet DMA Rx Descriptor interrupt */
620       DMARxDesc->ControlBufferSize &= ~ETH_DMARXDESC_DIC;
621     }
622 
623     /* Initialize the next descriptor with the Next Descriptor Polling Enable */
624     if (i < (RxBuffCount - 1U))
625     {
626       /* Set next descriptor address register with next descriptor base address */
627       DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1U);
628     }
629     else
630     {
631       /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
632       DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
633     }
634   }
635 
636   /* Set Receive Descriptor List Address Register */
637   (heth->Instance)->DMARDLAR = (uint32_t) DMARxDescTab;
638 
639   /* Set ETH HAL State to Ready */
640   heth->State = HAL_ETH_STATE_READY;
641 
642   /* Process Unlocked */
643   __HAL_UNLOCK(heth);
644 
645   /* Return function status */
646   return HAL_OK;
647 }
648 
649 /**
650   * @brief  Initializes the ETH MSP.
651   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
652   *         the configuration information for ETHERNET module
653   * @retval None
654   */
HAL_ETH_MspInit(ETH_HandleTypeDef * heth)655 __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
656 {
657   /* Prevent unused argument(s) compilation warning */
658   UNUSED(heth);
659   /* NOTE : This function Should not be modified, when the callback is needed,
660   the HAL_ETH_MspInit could be implemented in the user file
661   */
662 }
663 
664 /**
665   * @brief  DeInitializes ETH MSP.
666   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
667   *         the configuration information for ETHERNET module
668   * @retval None
669   */
HAL_ETH_MspDeInit(ETH_HandleTypeDef * heth)670 __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
671 {
672   /* Prevent unused argument(s) compilation warning */
673   UNUSED(heth);
674   /* NOTE : This function Should not be modified, when the callback is needed,
675   the HAL_ETH_MspDeInit could be implemented in the user file
676   */
677 }
678 
679 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
680 /**
681   * @brief  Register a User ETH Callback
682   *         To be used instead of the weak predefined callback
683   * @param heth eth handle
684   * @param CallbackID ID of the callback to be registered
685   *        This parameter can be one of the following values:
686   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
687   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
688   *          @arg @ref HAL_ETH_DMA_ERROR_CB_ID   DMA Error Callback ID
689   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
690   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
691   * @param pCallback pointer to the Callback function
692   * @retval status
693   */
HAL_ETH_RegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID,pETH_CallbackTypeDef pCallback)694 HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, pETH_CallbackTypeDef pCallback)
695 {
696   HAL_StatusTypeDef status = HAL_OK;
697 
698   if (pCallback == NULL)
699   {
700     return HAL_ERROR;
701   }
702   /* Process locked */
703   __HAL_LOCK(heth);
704 
705   if (heth->State == HAL_ETH_STATE_READY)
706   {
707     switch (CallbackID)
708     {
709       case HAL_ETH_TX_COMPLETE_CB_ID :
710         heth->TxCpltCallback = pCallback;
711         break;
712 
713       case HAL_ETH_RX_COMPLETE_CB_ID :
714         heth->RxCpltCallback = pCallback;
715         break;
716 
717       case HAL_ETH_DMA_ERROR_CB_ID :
718         heth->DMAErrorCallback = pCallback;
719         break;
720 
721       case HAL_ETH_MSPINIT_CB_ID :
722         heth->MspInitCallback = pCallback;
723         break;
724 
725       case HAL_ETH_MSPDEINIT_CB_ID :
726         heth->MspDeInitCallback = pCallback;
727         break;
728 
729       default :
730         /* Return error status */
731         status =  HAL_ERROR;
732         break;
733     }
734   }
735   else if (heth->State == HAL_ETH_STATE_RESET)
736   {
737     switch (CallbackID)
738     {
739       case HAL_ETH_MSPINIT_CB_ID :
740         heth->MspInitCallback = pCallback;
741         break;
742 
743       case HAL_ETH_MSPDEINIT_CB_ID :
744         heth->MspDeInitCallback = pCallback;
745         break;
746 
747       default :
748         /* Return error status */
749         status =  HAL_ERROR;
750         break;
751     }
752   }
753   else
754   {
755     /* Return error status */
756     status =  HAL_ERROR;
757   }
758 
759   /* Release Lock */
760   __HAL_UNLOCK(heth);
761 
762   return status;
763 }
764 
765 /**
766   * @brief  Unregister an ETH Callback
767   *         ETH callabck is redirected to the weak predefined callback
768   * @param heth eth handle
769   * @param CallbackID ID of the callback to be unregistered
770   *        This parameter can be one of the following values:
771   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
772   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
773   *          @arg @ref HAL_ETH_DMA_ERROR_CB_ID      DMA Error Callback ID
774   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
775   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
776   * @retval status
777   */
HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID)778 HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
779 {
780   HAL_StatusTypeDef status = HAL_OK;
781 
782   /* Process locked */
783   __HAL_LOCK(heth);
784 
785   if (heth->State == HAL_ETH_STATE_READY)
786   {
787     switch (CallbackID)
788     {
789       case HAL_ETH_TX_COMPLETE_CB_ID :
790         heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
791         break;
792 
793       case HAL_ETH_RX_COMPLETE_CB_ID :
794         heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
795         break;
796 
797       case HAL_ETH_DMA_ERROR_CB_ID :
798         heth->DMAErrorCallback = HAL_ETH_ErrorCallback;
799         break;
800 
801       case HAL_ETH_MSPINIT_CB_ID :
802         heth->MspInitCallback = HAL_ETH_MspInit;
803         break;
804 
805       case HAL_ETH_MSPDEINIT_CB_ID :
806         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
807         break;
808 
809       default :
810         /* Return error status */
811         status =  HAL_ERROR;
812         break;
813     }
814   }
815   else if (heth->State == HAL_ETH_STATE_RESET)
816   {
817     switch (CallbackID)
818     {
819       case HAL_ETH_MSPINIT_CB_ID :
820         heth->MspInitCallback = HAL_ETH_MspInit;
821         break;
822 
823       case HAL_ETH_MSPDEINIT_CB_ID :
824         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
825         break;
826 
827       default :
828         /* Return error status */
829         status =  HAL_ERROR;
830         break;
831     }
832   }
833   else
834   {
835     /* Return error status */
836     status =  HAL_ERROR;
837   }
838 
839   /* Release Lock */
840   __HAL_UNLOCK(heth);
841 
842   return status;
843 }
844 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
845 
846 /**
847   * @}
848   */
849 
850 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
851   *  @brief   Data transfers functions
852   *
853   @verbatim
854   ==============================================================================
855                           ##### IO operation functions #####
856   ==============================================================================
857   [..]  This section provides functions allowing to:
858         (+) Transmit a frame
859             HAL_ETH_TransmitFrame();
860         (+) Receive a frame
861             HAL_ETH_GetReceivedFrame();
862             HAL_ETH_GetReceivedFrame_IT();
863         (+) Read from an External PHY register
864             HAL_ETH_ReadPHYRegister();
865         (+) Write to an External PHY register
866             HAL_ETH_WritePHYRegister();
867 
868   @endverbatim
869 
870   * @{
871   */
872 
873 /**
874   * @brief  Sends an Ethernet frame.
875   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
876   *         the configuration information for ETHERNET module
877   * @param  FrameLength: Amount of data to be sent
878   * @retval HAL status
879   */
HAL_ETH_TransmitFrame(ETH_HandleTypeDef * heth,uint32_t FrameLength)880 HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
881 {
882   uint32_t bufcount = 0U, size = 0U, i = 0U;
883 
884   /* Process Locked */
885   __HAL_LOCK(heth);
886 
887   /* Set the ETH peripheral state to BUSY */
888   heth->State = HAL_ETH_STATE_BUSY;
889 
890   if (FrameLength == 0U)
891   {
892     /* Set ETH HAL state to READY */
893     heth->State = HAL_ETH_STATE_READY;
894 
895     /* Process Unlocked */
896     __HAL_UNLOCK(heth);
897 
898     return  HAL_ERROR;
899   }
900 
901   /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
902   if (((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
903   {
904     /* OWN bit set */
905     heth->State = HAL_ETH_STATE_BUSY_TX;
906 
907     /* Process Unlocked */
908     __HAL_UNLOCK(heth);
909 
910     return HAL_ERROR;
911   }
912 
913   /* Get the number of needed Tx buffers for the current frame */
914   if (FrameLength > ETH_TX_BUF_SIZE)
915   {
916     bufcount = FrameLength / ETH_TX_BUF_SIZE;
917     if (FrameLength % ETH_TX_BUF_SIZE)
918     {
919       bufcount++;
920     }
921   }
922   else
923   {
924     bufcount = 1U;
925   }
926   if (bufcount == 1U)
927   {
928     /* Set LAST and FIRST segment */
929     heth->TxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
930     /* Set frame size */
931     heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1);
932     /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
933     heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
934     /* Point to next descriptor */
935     heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
936   }
937   else
938   {
939     for (i = 0U; i < bufcount; i++)
940     {
941       /* Clear FIRST and LAST segment bits */
942       heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
943 
944       if (i == 0U)
945       {
946         /* Setting the first segment bit */
947         heth->TxDesc->Status |= ETH_DMATXDESC_FS;
948       }
949 
950       /* Program size */
951       heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
952 
953       if (i == (bufcount - 1U))
954       {
955         /* Setting the last segment bit */
956         heth->TxDesc->Status |= ETH_DMATXDESC_LS;
957         size = FrameLength - (bufcount - 1U) * ETH_TX_BUF_SIZE;
958         heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
959       }
960 
961       /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
962       heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
963       /* point to next descriptor */
964       heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
965     }
966   }
967 
968   /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
969   if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
970   {
971     /* Clear TBUS ETHERNET DMA flag */
972     (heth->Instance)->DMASR = ETH_DMASR_TBUS;
973     /* Resume DMA transmission*/
974     (heth->Instance)->DMATPDR = 0U;
975   }
976 
977   /* Set ETH HAL State to Ready */
978   heth->State = HAL_ETH_STATE_READY;
979 
980   /* Process Unlocked */
981   __HAL_UNLOCK(heth);
982 
983   /* Return function status */
984   return HAL_OK;
985 }
986 
987 /**
988   * @brief  Checks for received frames.
989   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
990   *         the configuration information for ETHERNET module
991   * @retval HAL status
992   */
HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef * heth)993 HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth)
994 {
995   uint32_t framelength = 0U;
996 
997   /* Process Locked */
998   __HAL_LOCK(heth);
999 
1000   /* Check the ETH state to BUSY */
1001   heth->State = HAL_ETH_STATE_BUSY;
1002 
1003   /* Check if segment is not owned by DMA */
1004   /* (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) */
1005   if (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET))
1006   {
1007     /* Check if last segment */
1008     if (((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET))
1009     {
1010       /* increment segment count */
1011       (heth->RxFrameInfos).SegCount++;
1012 
1013       /* Check if last segment is first segment: one segment contains the frame */
1014       if ((heth->RxFrameInfos).SegCount == 1U)
1015       {
1016         (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
1017       }
1018 
1019       heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
1020 
1021       /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
1022       framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
1023       heth->RxFrameInfos.length = framelength;
1024 
1025       /* Get the address of the buffer start address */
1026       heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
1027       /* point to next descriptor */
1028       heth->RxDesc = (ETH_DMADescTypeDef *)((heth->RxDesc)->Buffer2NextDescAddr);
1029 
1030       /* Set HAL State to Ready */
1031       heth->State = HAL_ETH_STATE_READY;
1032 
1033       /* Process Unlocked */
1034       __HAL_UNLOCK(heth);
1035 
1036       /* Return function status */
1037       return HAL_OK;
1038     }
1039     /* Check if first segment */
1040     else if ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET)
1041     {
1042       (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
1043       (heth->RxFrameInfos).LSRxDesc = NULL;
1044       (heth->RxFrameInfos).SegCount = 1U;
1045       /* Point to next descriptor */
1046       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1047     }
1048     /* Check if intermediate segment */
1049     else
1050     {
1051       (heth->RxFrameInfos).SegCount++;
1052       /* Point to next descriptor */
1053       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1054     }
1055   }
1056 
1057   /* Set ETH HAL State to Ready */
1058   heth->State = HAL_ETH_STATE_READY;
1059 
1060   /* Process Unlocked */
1061   __HAL_UNLOCK(heth);
1062 
1063   /* Return function status */
1064   return HAL_ERROR;
1065 }
1066 
1067 /**
1068   * @brief  Gets the Received frame in interrupt mode.
1069   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1070   *         the configuration information for ETHERNET module
1071   * @retval HAL status
1072   */
HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef * heth)1073 HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth)
1074 {
1075   uint32_t descriptorscancounter = 0U;
1076 
1077   /* Process Locked */
1078   __HAL_LOCK(heth);
1079 
1080   /* Set ETH HAL State to BUSY */
1081   heth->State = HAL_ETH_STATE_BUSY;
1082 
1083   /* Scan descriptors owned by CPU */
1084   while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (descriptorscancounter < ETH_RXBUFNB))
1085   {
1086     /* Just for security */
1087     descriptorscancounter++;
1088 
1089     /* Check if first segment in frame */
1090     /* ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)) */
1091     if ((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == (uint32_t)ETH_DMARXDESC_FS)
1092     {
1093       heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
1094       heth->RxFrameInfos.SegCount = 1U;
1095       /* Point to next descriptor */
1096       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1097     }
1098     /* Check if intermediate segment */
1099     /* ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)&& ((heth->RxDesc->Status & ETH_DMARXDESC_FS) == (uint32_t)RESET)) */
1100     else if ((heth->RxDesc->Status & (ETH_DMARXDESC_LS | ETH_DMARXDESC_FS)) == (uint32_t)RESET)
1101     {
1102       /* Increment segment count */
1103       (heth->RxFrameInfos.SegCount)++;
1104       /* Point to next descriptor */
1105       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1106     }
1107     /* Should be last segment */
1108     else
1109     {
1110       /* Last segment */
1111       heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
1112 
1113       /* Increment segment count */
1114       (heth->RxFrameInfos.SegCount)++;
1115 
1116       /* Check if last segment is first segment: one segment contains the frame */
1117       if ((heth->RxFrameInfos.SegCount) == 1U)
1118       {
1119         heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
1120       }
1121 
1122       /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
1123       heth->RxFrameInfos.length = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
1124 
1125       /* Get the address of the buffer start address */
1126       heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
1127 
1128       /* Point to next descriptor */
1129       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1130 
1131       /* Set HAL State to Ready */
1132       heth->State = HAL_ETH_STATE_READY;
1133 
1134       /* Process Unlocked */
1135       __HAL_UNLOCK(heth);
1136 
1137       /* Return function status */
1138       return HAL_OK;
1139     }
1140   }
1141 
1142   /* Set HAL State to Ready */
1143   heth->State = HAL_ETH_STATE_READY;
1144 
1145   /* Process Unlocked */
1146   __HAL_UNLOCK(heth);
1147 
1148   /* Return function status */
1149   return HAL_ERROR;
1150 }
1151 
1152 /**
1153   * @brief  This function handles ETH interrupt request.
1154   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1155   *         the configuration information for ETHERNET module
1156   * @retval HAL status
1157   */
HAL_ETH_IRQHandler(ETH_HandleTypeDef * heth)1158 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1159 {
1160   /* Frame received */
1161   if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R))
1162   {
1163 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1164     /*Call registered Receive complete callback*/
1165     heth->RxCpltCallback(heth);
1166 #else
1167     /* Receive complete callback */
1168     HAL_ETH_RxCpltCallback(heth);
1169 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1170 
1171     /* Clear the Eth DMA Rx IT pending bits */
1172     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R);
1173 
1174     /* Set HAL State to Ready */
1175     heth->State = HAL_ETH_STATE_READY;
1176 
1177     /* Process Unlocked */
1178     __HAL_UNLOCK(heth);
1179 
1180   }
1181   /* Frame transmitted */
1182   else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T))
1183   {
1184 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1185     /*  Call resgistered Transfer complete callback*/
1186     heth->TxCpltCallback(heth);
1187 #else
1188     /* Transfer complete callback */
1189     HAL_ETH_TxCpltCallback(heth);
1190 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1191 
1192     /* Clear the Eth DMA Tx IT pending bits */
1193     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T);
1194 
1195     /* Set HAL State to Ready */
1196     heth->State = HAL_ETH_STATE_READY;
1197 
1198     /* Process Unlocked */
1199     __HAL_UNLOCK(heth);
1200   }
1201 
1202   /* Clear the interrupt flags */
1203   __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS);
1204 
1205   /* ETH DMA Error */
1206   if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS))
1207   {
1208 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1209     heth->DMAErrorCallback(heth);
1210 #else
1211     /* Ethernet Error callback */
1212     HAL_ETH_ErrorCallback(heth);
1213 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1214 
1215     /* Clear the interrupt flags */
1216     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS);
1217 
1218     /* Set HAL State to Ready */
1219     heth->State = HAL_ETH_STATE_READY;
1220 
1221     /* Process Unlocked */
1222     __HAL_UNLOCK(heth);
1223   }
1224 }
1225 
1226 /**
1227   * @brief  Tx Transfer completed callbacks.
1228   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1229   *         the configuration information for ETHERNET module
1230   * @retval None
1231   */
HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth)1232 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
1233 {
1234   /* Prevent unused argument(s) compilation warning */
1235   UNUSED(heth);
1236   /* NOTE : This function Should not be modified, when the callback is needed,
1237   the HAL_ETH_TxCpltCallback could be implemented in the user file
1238   */
1239 }
1240 
1241 /**
1242   * @brief  Rx Transfer completed callbacks.
1243   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1244   *         the configuration information for ETHERNET module
1245   * @retval None
1246   */
HAL_ETH_RxCpltCallback(ETH_HandleTypeDef * heth)1247 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
1248 {
1249   /* Prevent unused argument(s) compilation warning */
1250   UNUSED(heth);
1251   /* NOTE : This function Should not be modified, when the callback is needed,
1252   the HAL_ETH_TxCpltCallback could be implemented in the user file
1253   */
1254 }
1255 
1256 /**
1257   * @brief  Ethernet transfer error callbacks
1258   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1259   *         the configuration information for ETHERNET module
1260   * @retval None
1261   */
HAL_ETH_ErrorCallback(ETH_HandleTypeDef * heth)1262 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
1263 {
1264   /* Prevent unused argument(s) compilation warning */
1265   UNUSED(heth);
1266   /* NOTE : This function Should not be modified, when the callback is needed,
1267   the HAL_ETH_TxCpltCallback could be implemented in the user file
1268   */
1269 }
1270 
1271 /**
1272   * @brief  Reads a PHY register
1273   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1274   *         the configuration information for ETHERNET module
1275   * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
1276   *                This parameter can be one of the following values:
1277   *                   PHY_BCR: Transceiver Basic Control Register,
1278   *                   PHY_BSR: Transceiver Basic Status Register.
1279   *                   More PHY register could be read depending on the used PHY
1280   * @param RegValue: PHY register value
1281   * @retval HAL status
1282   */
HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef * heth,uint16_t PHYReg,uint32_t * RegValue)1283 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
1284 {
1285   uint32_t tmpreg1 = 0U;
1286   uint32_t tickstart = 0U;
1287 
1288   /* Check parameters */
1289   assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
1290 
1291   /* Check the ETH peripheral state */
1292   if (heth->State == HAL_ETH_STATE_BUSY_RD)
1293   {
1294     return HAL_BUSY;
1295   }
1296   /* Set ETH HAL State to BUSY_RD */
1297   heth->State = HAL_ETH_STATE_BUSY_RD;
1298 
1299   /* Get the ETHERNET MACMIIAR value */
1300   tmpreg1 = heth->Instance->MACMIIAR;
1301 
1302   /* Keep only the CSR Clock Range CR[2:0] bits value */
1303   tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
1304 
1305   /* Prepare the MII address register value */
1306   tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address   */
1307   tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR);                /* Set the PHY register address */
1308   tmpreg1 &= ~ETH_MACMIIAR_MW;                                            /* Set the read mode            */
1309   tmpreg1 |= ETH_MACMIIAR_MB;                                             /* Set the MII Busy bit         */
1310 
1311   /* Write the result value into the MII Address register */
1312   heth->Instance->MACMIIAR = tmpreg1;
1313 
1314   /* Get tick */
1315   tickstart = HAL_GetTick();
1316 
1317   /* Check for the Busy flag */
1318   while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
1319   {
1320     /* Check for the Timeout */
1321     if ((HAL_GetTick() - tickstart) > PHY_READ_TO)
1322     {
1323       heth->State = HAL_ETH_STATE_READY;
1324 
1325       /* Process Unlocked */
1326       __HAL_UNLOCK(heth);
1327 
1328       return HAL_TIMEOUT;
1329     }
1330 
1331     tmpreg1 = heth->Instance->MACMIIAR;
1332   }
1333 
1334   /* Get MACMIIDR value */
1335   *RegValue = (uint16_t)(heth->Instance->MACMIIDR);
1336 
1337   /* Set ETH HAL State to READY */
1338   heth->State = HAL_ETH_STATE_READY;
1339 
1340   /* Return function status */
1341   return HAL_OK;
1342 }
1343 
1344 /**
1345   * @brief  Writes to a PHY register.
1346   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1347   *         the configuration information for ETHERNET module
1348   * @param  PHYReg: PHY register address, is the index of one of the 32 PHY register.
1349   *          This parameter can be one of the following values:
1350   *             PHY_BCR: Transceiver Control Register.
1351   *             More PHY register could be written depending on the used PHY
1352   * @param  RegValue: the value to write
1353   * @retval HAL status
1354   */
HAL_ETH_WritePHYRegister(ETH_HandleTypeDef * heth,uint16_t PHYReg,uint32_t RegValue)1355 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
1356 {
1357   uint32_t tmpreg1 = 0U;
1358   uint32_t tickstart = 0U;
1359 
1360   /* Check parameters */
1361   assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
1362 
1363   /* Check the ETH peripheral state */
1364   if (heth->State == HAL_ETH_STATE_BUSY_WR)
1365   {
1366     return HAL_BUSY;
1367   }
1368   /* Set ETH HAL State to BUSY_WR */
1369   heth->State = HAL_ETH_STATE_BUSY_WR;
1370 
1371   /* Get the ETHERNET MACMIIAR value */
1372   tmpreg1 = heth->Instance->MACMIIAR;
1373 
1374   /* Keep only the CSR Clock Range CR[2:0] bits value */
1375   tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
1376 
1377   /* Prepare the MII register address value */
1378   tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
1379   tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR);              /* Set the PHY register address */
1380   tmpreg1 |= ETH_MACMIIAR_MW;                                           /* Set the write mode */
1381   tmpreg1 |= ETH_MACMIIAR_MB;                                           /* Set the MII Busy bit */
1382 
1383   /* Give the value to the MII data register */
1384   heth->Instance->MACMIIDR = (uint16_t)RegValue;
1385 
1386   /* Write the result value into the MII Address register */
1387   heth->Instance->MACMIIAR = tmpreg1;
1388 
1389   /* Get tick */
1390   tickstart = HAL_GetTick();
1391 
1392   /* Check for the Busy flag */
1393   while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
1394   {
1395     /* Check for the Timeout */
1396     if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO)
1397     {
1398       heth->State = HAL_ETH_STATE_READY;
1399 
1400       /* Process Unlocked */
1401       __HAL_UNLOCK(heth);
1402 
1403       return HAL_TIMEOUT;
1404     }
1405 
1406     tmpreg1 = heth->Instance->MACMIIAR;
1407   }
1408 
1409   /* Set ETH HAL State to READY */
1410   heth->State = HAL_ETH_STATE_READY;
1411 
1412   /* Return function status */
1413   return HAL_OK;
1414 }
1415 
1416 /**
1417   * @}
1418   */
1419 
1420 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
1421  *  @brief    Peripheral Control functions
1422  *
1423 @verbatim
1424  ===============================================================================
1425                   ##### Peripheral Control functions #####
1426  ===============================================================================
1427     [..]  This section provides functions allowing to:
1428       (+) Enable MAC and DMA transmission and reception.
1429           HAL_ETH_Start();
1430       (+) Disable MAC and DMA transmission and reception.
1431           HAL_ETH_Stop();
1432       (+) Set the MAC configuration in runtime mode
1433           HAL_ETH_ConfigMAC();
1434       (+) Set the DMA configuration in runtime mode
1435           HAL_ETH_ConfigDMA();
1436 
1437 @endverbatim
1438   * @{
1439   */
1440 
1441 /**
1442  * @brief  Enables Ethernet MAC and DMA reception/transmission
1443  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1444  *         the configuration information for ETHERNET module
1445  * @retval HAL status
1446  */
HAL_ETH_Start(ETH_HandleTypeDef * heth)1447 HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
1448 {
1449   /* Process Locked */
1450   __HAL_LOCK(heth);
1451 
1452   /* Set the ETH peripheral state to BUSY */
1453   heth->State = HAL_ETH_STATE_BUSY;
1454 
1455   /* Enable transmit state machine of the MAC for transmission on the MII */
1456   ETH_MACTransmissionEnable(heth);
1457 
1458   /* Enable receive state machine of the MAC for reception from the MII */
1459   ETH_MACReceptionEnable(heth);
1460 
1461   /* Flush Transmit FIFO */
1462   ETH_FlushTransmitFIFO(heth);
1463 
1464   /* Start DMA transmission */
1465   ETH_DMATransmissionEnable(heth);
1466 
1467   /* Start DMA reception */
1468   ETH_DMAReceptionEnable(heth);
1469 
1470   /* Set the ETH state to READY*/
1471   heth->State = HAL_ETH_STATE_READY;
1472 
1473   /* Process Unlocked */
1474   __HAL_UNLOCK(heth);
1475 
1476   /* Return function status */
1477   return HAL_OK;
1478 }
1479 
1480 /**
1481   * @brief  Stop Ethernet MAC and DMA reception/transmission
1482   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1483   *         the configuration information for ETHERNET module
1484   * @retval HAL status
1485   */
HAL_ETH_Stop(ETH_HandleTypeDef * heth)1486 HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
1487 {
1488   /* Process Locked */
1489   __HAL_LOCK(heth);
1490 
1491   /* Set the ETH peripheral state to BUSY */
1492   heth->State = HAL_ETH_STATE_BUSY;
1493 
1494   /* Stop DMA transmission */
1495   ETH_DMATransmissionDisable(heth);
1496 
1497   /* Stop DMA reception */
1498   ETH_DMAReceptionDisable(heth);
1499 
1500   /* Disable receive state machine of the MAC for reception from the MII */
1501   ETH_MACReceptionDisable(heth);
1502 
1503   /* Flush Transmit FIFO */
1504   ETH_FlushTransmitFIFO(heth);
1505 
1506   /* Disable transmit state machine of the MAC for transmission on the MII */
1507   ETH_MACTransmissionDisable(heth);
1508 
1509   /* Set the ETH state*/
1510   heth->State = HAL_ETH_STATE_READY;
1511 
1512   /* Process Unlocked */
1513   __HAL_UNLOCK(heth);
1514 
1515   /* Return function status */
1516   return HAL_OK;
1517 }
1518 
1519 /**
1520   * @brief  Set ETH MAC Configuration.
1521   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1522   *         the configuration information for ETHERNET module
1523   * @param  macconf: MAC Configuration structure
1524   * @retval HAL status
1525   */
HAL_ETH_ConfigMAC(ETH_HandleTypeDef * heth,ETH_MACInitTypeDef * macconf)1526 HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
1527 {
1528   uint32_t tmpreg1 = 0U;
1529 
1530   /* Process Locked */
1531   __HAL_LOCK(heth);
1532 
1533   /* Set the ETH peripheral state to BUSY */
1534   heth->State = HAL_ETH_STATE_BUSY;
1535 
1536   assert_param(IS_ETH_SPEED(heth->Init.Speed));
1537   assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
1538 
1539   if (macconf != NULL)
1540   {
1541     /* Check the parameters */
1542     assert_param(IS_ETH_WATCHDOG(macconf->Watchdog));
1543     assert_param(IS_ETH_JABBER(macconf->Jabber));
1544     assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap));
1545     assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense));
1546     assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn));
1547     assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode));
1548     assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload));
1549     assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission));
1550     assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip));
1551     assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit));
1552     assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck));
1553     assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll));
1554     assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter));
1555     assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames));
1556     assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception));
1557     assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter));
1558     assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode));
1559     assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter));
1560     assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter));
1561     assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime));
1562     assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause));
1563     assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold));
1564     assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect));
1565     assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl));
1566     assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl));
1567     assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison));
1568     assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier));
1569 
1570     /*------------------------ ETHERNET MACCR Configuration --------------------*/
1571     /* Get the ETHERNET MACCR value */
1572     tmpreg1 = (heth->Instance)->MACCR;
1573     /* Clear WD, PCE, PS, TE and RE bits */
1574     tmpreg1 &= ETH_MACCR_CLEAR_MASK;
1575 
1576     tmpreg1 |= (uint32_t)(macconf->Watchdog |
1577                           macconf->Jabber |
1578                           macconf->InterFrameGap |
1579                           macconf->CarrierSense |
1580                           (heth->Init).Speed |
1581                           macconf->ReceiveOwn |
1582                           macconf->LoopbackMode |
1583                           (heth->Init).DuplexMode |
1584                           macconf->ChecksumOffload |
1585                           macconf->RetryTransmission |
1586                           macconf->AutomaticPadCRCStrip |
1587                           macconf->BackOffLimit |
1588                           macconf->DeferralCheck);
1589 
1590     /* Write to ETHERNET MACCR */
1591     (heth->Instance)->MACCR = (uint32_t)tmpreg1;
1592 
1593     /* Wait until the write operation will be taken into account :
1594     at least four TX_CLK/RX_CLK clock cycles */
1595     tmpreg1 = (heth->Instance)->MACCR;
1596     HAL_Delay(ETH_REG_WRITE_DELAY);
1597     (heth->Instance)->MACCR = tmpreg1;
1598 
1599     /*----------------------- ETHERNET MACFFR Configuration --------------------*/
1600     /* Write to ETHERNET MACFFR */
1601     (heth->Instance)->MACFFR = (uint32_t)(macconf->ReceiveAll |
1602                                           macconf->SourceAddrFilter |
1603                                           macconf->PassControlFrames |
1604                                           macconf->BroadcastFramesReception |
1605                                           macconf->DestinationAddrFilter |
1606                                           macconf->PromiscuousMode |
1607                                           macconf->MulticastFramesFilter |
1608                                           macconf->UnicastFramesFilter);
1609 
1610     /* Wait until the write operation will be taken into account :
1611     at least four TX_CLK/RX_CLK clock cycles */
1612     tmpreg1 = (heth->Instance)->MACFFR;
1613     HAL_Delay(ETH_REG_WRITE_DELAY);
1614     (heth->Instance)->MACFFR = tmpreg1;
1615 
1616     /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
1617     /* Write to ETHERNET MACHTHR */
1618     (heth->Instance)->MACHTHR = (uint32_t)macconf->HashTableHigh;
1619 
1620     /* Write to ETHERNET MACHTLR */
1621     (heth->Instance)->MACHTLR = (uint32_t)macconf->HashTableLow;
1622     /*----------------------- ETHERNET MACFCR Configuration --------------------*/
1623 
1624     /* Get the ETHERNET MACFCR value */
1625     tmpreg1 = (heth->Instance)->MACFCR;
1626     /* Clear xx bits */
1627     tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
1628 
1629     tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) |
1630                           macconf->ZeroQuantaPause |
1631                           macconf->PauseLowThreshold |
1632                           macconf->UnicastPauseFrameDetect |
1633                           macconf->ReceiveFlowControl |
1634                           macconf->TransmitFlowControl);
1635 
1636     /* Write to ETHERNET MACFCR */
1637     (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
1638 
1639     /* Wait until the write operation will be taken into account :
1640     at least four TX_CLK/RX_CLK clock cycles */
1641     tmpreg1 = (heth->Instance)->MACFCR;
1642     HAL_Delay(ETH_REG_WRITE_DELAY);
1643     (heth->Instance)->MACFCR = tmpreg1;
1644 
1645     /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
1646     (heth->Instance)->MACVLANTR = (uint32_t)(macconf->VLANTagComparison |
1647                                              macconf->VLANTagIdentifier);
1648 
1649     /* Wait until the write operation will be taken into account :
1650     at least four TX_CLK/RX_CLK clock cycles */
1651     tmpreg1 = (heth->Instance)->MACVLANTR;
1652     HAL_Delay(ETH_REG_WRITE_DELAY);
1653     (heth->Instance)->MACVLANTR = tmpreg1;
1654   }
1655   else /* macconf == NULL : here we just configure Speed and Duplex mode */
1656   {
1657     /*------------------------ ETHERNET MACCR Configuration --------------------*/
1658     /* Get the ETHERNET MACCR value */
1659     tmpreg1 = (heth->Instance)->MACCR;
1660 
1661     /* Clear FES and DM bits */
1662     tmpreg1 &= ~(0x00004800U);
1663 
1664     tmpreg1 |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
1665 
1666     /* Write to ETHERNET MACCR */
1667     (heth->Instance)->MACCR = (uint32_t)tmpreg1;
1668 
1669     /* Wait until the write operation will be taken into account:
1670     at least four TX_CLK/RX_CLK clock cycles */
1671     tmpreg1 = (heth->Instance)->MACCR;
1672     HAL_Delay(ETH_REG_WRITE_DELAY);
1673     (heth->Instance)->MACCR = tmpreg1;
1674   }
1675 
1676   /* Set the ETH state to Ready */
1677   heth->State = HAL_ETH_STATE_READY;
1678 
1679   /* Process Unlocked */
1680   __HAL_UNLOCK(heth);
1681 
1682   /* Return function status */
1683   return HAL_OK;
1684 }
1685 
1686 /**
1687   * @brief  Sets ETH DMA Configuration.
1688   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1689   *         the configuration information for ETHERNET module
1690   * @param  dmaconf: DMA Configuration structure
1691   * @retval HAL status
1692   */
HAL_ETH_ConfigDMA(ETH_HandleTypeDef * heth,ETH_DMAInitTypeDef * dmaconf)1693 HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
1694 {
1695   uint32_t tmpreg1 = 0U;
1696 
1697   /* Process Locked */
1698   __HAL_LOCK(heth);
1699 
1700   /* Set the ETH peripheral state to BUSY */
1701   heth->State = HAL_ETH_STATE_BUSY;
1702 
1703   /* Check parameters */
1704   assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame));
1705   assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward));
1706   assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame));
1707   assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward));
1708   assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl));
1709   assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames));
1710   assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames));
1711   assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl));
1712   assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate));
1713   assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats));
1714   assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst));
1715   assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength));
1716   assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength));
1717   assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength));
1718   assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration));
1719 
1720   /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
1721   /* Get the ETHERNET DMAOMR value */
1722   tmpreg1 = (heth->Instance)->DMAOMR;
1723   /* Clear xx bits */
1724   tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
1725 
1726   tmpreg1 |= (uint32_t)(dmaconf->DropTCPIPChecksumErrorFrame |
1727                         dmaconf->ReceiveStoreForward |
1728                         dmaconf->FlushReceivedFrame |
1729                         dmaconf->TransmitStoreForward |
1730                         dmaconf->TransmitThresholdControl |
1731                         dmaconf->ForwardErrorFrames |
1732                         dmaconf->ForwardUndersizedGoodFrames |
1733                         dmaconf->ReceiveThresholdControl |
1734                         dmaconf->SecondFrameOperate);
1735 
1736   /* Write to ETHERNET DMAOMR */
1737   (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
1738 
1739   /* Wait until the write operation will be taken into account:
1740   at least four TX_CLK/RX_CLK clock cycles */
1741   tmpreg1 = (heth->Instance)->DMAOMR;
1742   HAL_Delay(ETH_REG_WRITE_DELAY);
1743   (heth->Instance)->DMAOMR = tmpreg1;
1744 
1745   /*----------------------- ETHERNET DMABMR Configuration --------------------*/
1746   (heth->Instance)->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats |
1747                                         dmaconf->FixedBurst |
1748                                         dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
1749                                         dmaconf->TxDMABurstLength |
1750                                         (dmaconf->DescriptorSkipLength << 2U) |
1751                                         dmaconf->DMAArbitration |
1752                                         ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
1753 
1754   /* Wait until the write operation will be taken into account:
1755      at least four TX_CLK/RX_CLK clock cycles */
1756   tmpreg1 = (heth->Instance)->DMABMR;
1757   HAL_Delay(ETH_REG_WRITE_DELAY);
1758   (heth->Instance)->DMABMR = tmpreg1;
1759 
1760   /* Set the ETH state to Ready */
1761   heth->State = HAL_ETH_STATE_READY;
1762 
1763   /* Process Unlocked */
1764   __HAL_UNLOCK(heth);
1765 
1766   /* Return function status */
1767   return HAL_OK;
1768 }
1769 
1770 /**
1771   * @}
1772   */
1773 
1774 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions
1775   *  @brief   Peripheral State functions
1776   *
1777   @verbatim
1778   ===============================================================================
1779                          ##### Peripheral State functions #####
1780   ===============================================================================
1781   [..]
1782   This subsection permits to get in run-time the status of the peripheral
1783   and the data flow.
1784        (+) Get the ETH handle state:
1785            HAL_ETH_GetState();
1786 
1787 
1788   @endverbatim
1789   * @{
1790   */
1791 
1792 /**
1793   * @brief  Return the ETH HAL state
1794   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1795   *         the configuration information for ETHERNET module
1796   * @retval HAL state
1797   */
HAL_ETH_GetState(ETH_HandleTypeDef * heth)1798 HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
1799 {
1800   /* Return ETH state */
1801   return heth->State;
1802 }
1803 
1804 /**
1805   * @}
1806   */
1807 
1808 /**
1809   * @}
1810   */
1811 
1812 /** @addtogroup ETH_Private_Functions
1813   * @{
1814   */
1815 
1816 /**
1817   * @brief  Configures Ethernet MAC and DMA with default parameters.
1818   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1819   *         the configuration information for ETHERNET module
1820   * @param  err: Ethernet Init error
1821   * @retval HAL status
1822   */
ETH_MACDMAConfig(ETH_HandleTypeDef * heth,uint32_t err)1823 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
1824 {
1825   ETH_MACInitTypeDef macinit;
1826   ETH_DMAInitTypeDef dmainit;
1827   uint32_t tmpreg1 = 0U;
1828 
1829   if (err != ETH_SUCCESS) /* Auto-negotiation failed */
1830   {
1831     /* Set Ethernet duplex mode to Full-duplex */
1832     (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
1833 
1834     /* Set Ethernet speed to 100M */
1835     (heth->Init).Speed = ETH_SPEED_100M;
1836   }
1837 
1838   /* Ethernet MAC default initialization **************************************/
1839   macinit.Watchdog = ETH_WATCHDOG_ENABLE;
1840   macinit.Jabber = ETH_JABBER_ENABLE;
1841   macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
1842   macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
1843   macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
1844   macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
1845   if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
1846   {
1847     macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
1848   }
1849   else
1850   {
1851     macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
1852   }
1853   macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
1854   macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
1855   macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
1856   macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
1857   macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
1858   macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
1859   macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
1860   macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
1861   macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
1862   macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
1863   macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
1864   macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
1865   macinit.HashTableHigh = 0x0U;
1866   macinit.HashTableLow = 0x0U;
1867   macinit.PauseTime = 0x0U;
1868   macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
1869   macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
1870   macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
1871   macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
1872   macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
1873   macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
1874   macinit.VLANTagIdentifier = 0x0U;
1875 
1876   /*------------------------ ETHERNET MACCR Configuration --------------------*/
1877   /* Get the ETHERNET MACCR value */
1878   tmpreg1 = (heth->Instance)->MACCR;
1879   /* Clear WD, PCE, PS, TE and RE bits */
1880   tmpreg1 &= ETH_MACCR_CLEAR_MASK;
1881   /* Set the WD bit according to ETH Watchdog value */
1882   /* Set the JD: bit according to ETH Jabber value */
1883   /* Set the IFG bit according to ETH InterFrameGap value */
1884   /* Set the DCRS bit according to ETH CarrierSense value */
1885   /* Set the FES bit according to ETH Speed value */
1886   /* Set the DO bit according to ETH ReceiveOwn value */
1887   /* Set the LM bit according to ETH LoopbackMode value */
1888   /* Set the DM bit according to ETH Mode value */
1889   /* Set the IPCO bit according to ETH ChecksumOffload value */
1890   /* Set the DR bit according to ETH RetryTransmission value */
1891   /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
1892   /* Set the BL bit according to ETH BackOffLimit value */
1893   /* Set the DC bit according to ETH DeferralCheck value */
1894   tmpreg1 |= (uint32_t)(macinit.Watchdog |
1895                         macinit.Jabber |
1896                         macinit.InterFrameGap |
1897                         macinit.CarrierSense |
1898                         (heth->Init).Speed |
1899                         macinit.ReceiveOwn |
1900                         macinit.LoopbackMode |
1901                         (heth->Init).DuplexMode |
1902                         macinit.ChecksumOffload |
1903                         macinit.RetryTransmission |
1904                         macinit.AutomaticPadCRCStrip |
1905                         macinit.BackOffLimit |
1906                         macinit.DeferralCheck);
1907 
1908   /* Write to ETHERNET MACCR */
1909   (heth->Instance)->MACCR = (uint32_t)tmpreg1;
1910 
1911   /* Wait until the write operation will be taken into account:
1912      at least four TX_CLK/RX_CLK clock cycles */
1913   tmpreg1 = (heth->Instance)->MACCR;
1914   HAL_Delay(ETH_REG_WRITE_DELAY);
1915   (heth->Instance)->MACCR = tmpreg1;
1916 
1917   /*----------------------- ETHERNET MACFFR Configuration --------------------*/
1918   /* Set the RA bit according to ETH ReceiveAll value */
1919   /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
1920   /* Set the PCF bit according to ETH PassControlFrames value */
1921   /* Set the DBF bit according to ETH BroadcastFramesReception value */
1922   /* Set the DAIF bit according to ETH DestinationAddrFilter value */
1923   /* Set the PR bit according to ETH PromiscuousMode value */
1924   /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
1925   /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
1926   /* Write to ETHERNET MACFFR */
1927   (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
1928                                         macinit.SourceAddrFilter |
1929                                         macinit.PassControlFrames |
1930                                         macinit.BroadcastFramesReception |
1931                                         macinit.DestinationAddrFilter |
1932                                         macinit.PromiscuousMode |
1933                                         macinit.MulticastFramesFilter |
1934                                         macinit.UnicastFramesFilter);
1935 
1936   /* Wait until the write operation will be taken into account:
1937      at least four TX_CLK/RX_CLK clock cycles */
1938   tmpreg1 = (heth->Instance)->MACFFR;
1939   HAL_Delay(ETH_REG_WRITE_DELAY);
1940   (heth->Instance)->MACFFR = tmpreg1;
1941 
1942   /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
1943   /* Write to ETHERNET MACHTHR */
1944   (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
1945 
1946   /* Write to ETHERNET MACHTLR */
1947   (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;
1948   /*----------------------- ETHERNET MACFCR Configuration -------------------*/
1949 
1950   /* Get the ETHERNET MACFCR value */
1951   tmpreg1 = (heth->Instance)->MACFCR;
1952   /* Clear xx bits */
1953   tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
1954 
1955   /* Set the PT bit according to ETH PauseTime value */
1956   /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
1957   /* Set the PLT bit according to ETH PauseLowThreshold value */
1958   /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
1959   /* Set the RFE bit according to ETH ReceiveFlowControl value */
1960   /* Set the TFE bit according to ETH TransmitFlowControl value */
1961   tmpreg1 |= (uint32_t)((macinit.PauseTime << 16U) |
1962                         macinit.ZeroQuantaPause |
1963                         macinit.PauseLowThreshold |
1964                         macinit.UnicastPauseFrameDetect |
1965                         macinit.ReceiveFlowControl |
1966                         macinit.TransmitFlowControl);
1967 
1968   /* Write to ETHERNET MACFCR */
1969   (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
1970 
1971   /* Wait until the write operation will be taken into account:
1972   at least four TX_CLK/RX_CLK clock cycles */
1973   tmpreg1 = (heth->Instance)->MACFCR;
1974   HAL_Delay(ETH_REG_WRITE_DELAY);
1975   (heth->Instance)->MACFCR = tmpreg1;
1976 
1977   /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
1978   /* Set the ETV bit according to ETH VLANTagComparison value */
1979   /* Set the VL bit according to ETH VLANTagIdentifier value */
1980   (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
1981                                            macinit.VLANTagIdentifier);
1982 
1983   /* Wait until the write operation will be taken into account:
1984      at least four TX_CLK/RX_CLK clock cycles */
1985   tmpreg1 = (heth->Instance)->MACVLANTR;
1986   HAL_Delay(ETH_REG_WRITE_DELAY);
1987   (heth->Instance)->MACVLANTR = tmpreg1;
1988 
1989   /* Ethernet DMA default initialization ************************************/
1990   dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
1991   dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
1992   dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
1993   dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
1994   dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
1995   dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
1996   dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
1997   dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
1998   dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
1999   dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
2000   dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
2001   dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2002   dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2003   dmainit.DescriptorSkipLength = 0x0U;
2004   dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
2005 
2006   /* Get the ETHERNET DMAOMR value */
2007   tmpreg1 = (heth->Instance)->DMAOMR;
2008   /* Clear xx bits */
2009   tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
2010 
2011   /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
2012   /* Set the RSF bit according to ETH ReceiveStoreForward value */
2013   /* Set the DFF bit according to ETH FlushReceivedFrame value */
2014   /* Set the TSF bit according to ETH TransmitStoreForward value */
2015   /* Set the TTC bit according to ETH TransmitThresholdControl value */
2016   /* Set the FEF bit according to ETH ForwardErrorFrames value */
2017   /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
2018   /* Set the RTC bit according to ETH ReceiveThresholdControl value */
2019   /* Set the OSF bit according to ETH SecondFrameOperate value */
2020   tmpreg1 |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
2021                         dmainit.ReceiveStoreForward |
2022                         dmainit.FlushReceivedFrame |
2023                         dmainit.TransmitStoreForward |
2024                         dmainit.TransmitThresholdControl |
2025                         dmainit.ForwardErrorFrames |
2026                         dmainit.ForwardUndersizedGoodFrames |
2027                         dmainit.ReceiveThresholdControl |
2028                         dmainit.SecondFrameOperate);
2029 
2030   /* Write to ETHERNET DMAOMR */
2031   (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
2032 
2033   /* Wait until the write operation will be taken into account:
2034      at least four TX_CLK/RX_CLK clock cycles */
2035   tmpreg1 = (heth->Instance)->DMAOMR;
2036   HAL_Delay(ETH_REG_WRITE_DELAY);
2037   (heth->Instance)->DMAOMR = tmpreg1;
2038 
2039   /*----------------------- ETHERNET DMABMR Configuration ------------------*/
2040   /* Set the AAL bit according to ETH AddressAlignedBeats value */
2041   /* Set the FB bit according to ETH FixedBurst value */
2042   /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
2043   /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
2044   /* Set the DSL bit according to ETH DesciptorSkipLength value */
2045   /* Set the PR and DA bits according to ETH DMAArbitration value */
2046   (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
2047                                         dmainit.FixedBurst |
2048                                         dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
2049                                         dmainit.TxDMABurstLength |
2050                                         (dmainit.DescriptorSkipLength << 2U) |
2051                                         dmainit.DMAArbitration |
2052                                         ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
2053 
2054   /* Wait until the write operation will be taken into account:
2055      at least four TX_CLK/RX_CLK clock cycles */
2056   tmpreg1 = (heth->Instance)->DMABMR;
2057   HAL_Delay(ETH_REG_WRITE_DELAY);
2058   (heth->Instance)->DMABMR = tmpreg1;
2059 
2060   if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
2061   {
2062     /* Enable the Ethernet Rx Interrupt */
2063     __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
2064   }
2065 
2066   /* Initialize MAC address in ethernet MAC */
2067   ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
2068 }
2069 
2070 /**
2071   * @brief  Configures the selected MAC address.
2072   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2073   *         the configuration information for ETHERNET module
2074   * @param  MacAddr: The MAC address to configure
2075   *          This parameter can be one of the following values:
2076   *             @arg ETH_MAC_Address0: MAC Address0
2077   *             @arg ETH_MAC_Address1: MAC Address1
2078   *             @arg ETH_MAC_Address2: MAC Address2
2079   *             @arg ETH_MAC_Address3: MAC Address3
2080   * @param  Addr: Pointer to MAC address buffer data (6 bytes)
2081   * @retval HAL status
2082   */
ETH_MACAddressConfig(ETH_HandleTypeDef * heth,uint32_t MacAddr,uint8_t * Addr)2083 static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
2084 {
2085   uint32_t tmpreg1;
2086 
2087   /* Prevent unused argument(s) compilation warning */
2088   UNUSED(heth);
2089 
2090   /* Check the parameters */
2091   assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
2092 
2093   /* Calculate the selected MAC address high register */
2094   tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U];
2095   /* Load the selected MAC address high register */
2096   (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1;
2097   /* Calculate the selected MAC address low register */
2098   tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U];
2099 
2100   /* Load the selected MAC address low register */
2101   (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1;
2102 }
2103 
2104 /**
2105   * @brief  Enables the MAC transmission.
2106   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2107   *         the configuration information for ETHERNET module
2108   * @retval None
2109   */
ETH_MACTransmissionEnable(ETH_HandleTypeDef * heth)2110 static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth)
2111 {
2112   __IO uint32_t tmpreg1 = 0U;
2113 
2114   /* Enable the MAC transmission */
2115   (heth->Instance)->MACCR |= ETH_MACCR_TE;
2116 
2117   /* Wait until the write operation will be taken into account:
2118      at least four TX_CLK/RX_CLK clock cycles */
2119   tmpreg1 = (heth->Instance)->MACCR;
2120   ETH_Delay(ETH_REG_WRITE_DELAY);
2121   (heth->Instance)->MACCR = tmpreg1;
2122 }
2123 
2124 /**
2125   * @brief  Disables the MAC transmission.
2126   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2127   *         the configuration information for ETHERNET module
2128   * @retval None
2129   */
ETH_MACTransmissionDisable(ETH_HandleTypeDef * heth)2130 static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth)
2131 {
2132   __IO uint32_t tmpreg1 = 0U;
2133 
2134   /* Disable the MAC transmission */
2135   (heth->Instance)->MACCR &= ~ETH_MACCR_TE;
2136 
2137   /* Wait until the write operation will be taken into account:
2138      at least four TX_CLK/RX_CLK clock cycles */
2139   tmpreg1 = (heth->Instance)->MACCR;
2140   ETH_Delay(ETH_REG_WRITE_DELAY);
2141   (heth->Instance)->MACCR = tmpreg1;
2142 }
2143 
2144 /**
2145   * @brief  Enables the MAC reception.
2146   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2147   *         the configuration information for ETHERNET module
2148   * @retval None
2149   */
ETH_MACReceptionEnable(ETH_HandleTypeDef * heth)2150 static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth)
2151 {
2152   __IO uint32_t tmpreg1 = 0U;
2153 
2154   /* Enable the MAC reception */
2155   (heth->Instance)->MACCR |= ETH_MACCR_RE;
2156 
2157   /* Wait until the write operation will be taken into account:
2158      at least four TX_CLK/RX_CLK clock cycles */
2159   tmpreg1 = (heth->Instance)->MACCR;
2160   ETH_Delay(ETH_REG_WRITE_DELAY);
2161   (heth->Instance)->MACCR = tmpreg1;
2162 }
2163 
2164 /**
2165   * @brief  Disables the MAC reception.
2166   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2167   *         the configuration information for ETHERNET module
2168   * @retval None
2169   */
ETH_MACReceptionDisable(ETH_HandleTypeDef * heth)2170 static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth)
2171 {
2172   __IO uint32_t tmpreg1 = 0U;
2173 
2174   /* Disable the MAC reception */
2175   (heth->Instance)->MACCR &= ~ETH_MACCR_RE;
2176 
2177   /* Wait until the write operation will be taken into account:
2178      at least four TX_CLK/RX_CLK clock cycles */
2179   tmpreg1 = (heth->Instance)->MACCR;
2180   ETH_Delay(ETH_REG_WRITE_DELAY);
2181   (heth->Instance)->MACCR = tmpreg1;
2182 }
2183 
2184 /**
2185   * @brief  Enables the DMA transmission.
2186   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2187   *         the configuration information for ETHERNET module
2188   * @retval None
2189   */
ETH_DMATransmissionEnable(ETH_HandleTypeDef * heth)2190 static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth)
2191 {
2192   /* Enable the DMA transmission */
2193   (heth->Instance)->DMAOMR |= ETH_DMAOMR_ST;
2194 }
2195 
2196 /**
2197   * @brief  Disables the DMA transmission.
2198   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2199   *         the configuration information for ETHERNET module
2200   * @retval None
2201   */
ETH_DMATransmissionDisable(ETH_HandleTypeDef * heth)2202 static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth)
2203 {
2204   /* Disable the DMA transmission */
2205   (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_ST;
2206 }
2207 
2208 /**
2209   * @brief  Enables the DMA reception.
2210   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2211   *         the configuration information for ETHERNET module
2212   * @retval None
2213   */
ETH_DMAReceptionEnable(ETH_HandleTypeDef * heth)2214 static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth)
2215 {
2216   /* Enable the DMA reception */
2217   (heth->Instance)->DMAOMR |= ETH_DMAOMR_SR;
2218 }
2219 
2220 /**
2221   * @brief  Disables the DMA reception.
2222   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2223   *         the configuration information for ETHERNET module
2224   * @retval None
2225   */
ETH_DMAReceptionDisable(ETH_HandleTypeDef * heth)2226 static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth)
2227 {
2228   /* Disable the DMA reception */
2229   (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_SR;
2230 }
2231 
2232 /**
2233   * @brief  Clears the ETHERNET transmit FIFO.
2234   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2235   *         the configuration information for ETHERNET module
2236   * @retval None
2237   */
ETH_FlushTransmitFIFO(ETH_HandleTypeDef * heth)2238 static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
2239 {
2240   __IO uint32_t tmpreg1 = 0U;
2241 
2242   /* Set the Flush Transmit FIFO bit */
2243   (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;
2244 
2245   /* Wait until the write operation will be taken into account:
2246      at least four TX_CLK/RX_CLK clock cycles */
2247   tmpreg1 = (heth->Instance)->DMAOMR;
2248   ETH_Delay(ETH_REG_WRITE_DELAY);
2249   (heth->Instance)->DMAOMR = tmpreg1;
2250 }
2251 
2252 /**
2253   * @brief  This function provides delay (in milliseconds) based on CPU cycles method.
2254   * @param  mdelay: specifies the delay time length, in milliseconds.
2255   * @retval None
2256   */
ETH_Delay(uint32_t mdelay)2257 static void ETH_Delay(uint32_t mdelay)
2258 {
2259   __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
2260   do
2261   {
2262     __NOP();
2263   }
2264   while (Delay --);
2265 }
2266 
2267 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
ETH_InitCallbacksToDefault(ETH_HandleTypeDef * heth)2268 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
2269 {
2270   /* Init the ETH Callback settings */
2271   heth->TxCpltCallback       = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback   */
2272   heth->RxCpltCallback       = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback   */
2273   heth->DMAErrorCallback     = HAL_ETH_ErrorCallback;  /* Legacy weak DMAErrorCallback */
2274 }
2275 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2276 
2277 /**
2278   * @}
2279   */
2280 
2281 #endif /* ETH */
2282 
2283 #endif /* HAL_ETH_MODULE_ENABLED */
2284 /**
2285   * @}
2286   */
2287 
2288 /**
2289   * @}
2290   */
2291 
2292 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2293