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