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