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