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