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