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