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