1 /**
2 ******************************************************************************
3 * @file stm32h7xx_hal_eth.c
4 * @author MCD Application Team
5 * @brief ETH HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Ethernet (ETH) peripheral:
8 * + Initialization and deinitialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + Peripheral State and Errors functions
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2017 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 The ETH HAL driver can be used as follows:
30
31 (#)Declare a ETH_HandleTypeDef handle structure, for example:
32 ETH_HandleTypeDef heth;
33
34 (#)Fill parameters of Init structure in heth handle
35
36 (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
37
38 (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
39 (##) Enable the Ethernet interface clock using
40 (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE()
41 (+++) __HAL_RCC_ETH1TX_CLK_ENABLE()
42 (+++) __HAL_RCC_ETH1RX_CLK_ENABLE()
43
44 (##) Initialize the related GPIO clocks
45 (##) Configure Ethernet pinout
46 (##) Configure Ethernet NVIC interrupt (in Interrupt mode)
47
48 (#) Ethernet data reception is asynchronous, so call the following API
49 to start the listening mode:
50 (##) HAL_ETH_Start():
51 This API starts the MAC and DMA transmission and reception process,
52 without enabling end of transfer interrupts, in this mode user
53 has to poll for data reception by calling HAL_ETH_ReadData()
54 (##) HAL_ETH_Start_IT():
55 This API starts the MAC and DMA transmission and reception process,
56 end of transfer interrupts are enabled in this mode,
57 HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received
58
59 (#) When data is received user can call the following API to get received data:
60 (##) HAL_ETH_ReadData(): Read a received packet
61
62 (#) For transmission path, two APIs are available:
63 (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode
64 (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode,
65 HAL_ETH_TxCpltCallback() will be executed when end of transfer occur
66
67 (#) Communication with an external PHY device:
68 (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY
69 (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register
70
71 (#) Configure the Ethernet MAC after ETH peripheral initialization
72 (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef
73 (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef
74
75 (#) Configure the Ethernet DMA after ETH peripheral initialization
76 (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef
77 (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef
78
79 (#) Configure the Ethernet PTP after ETH peripheral initialization
80 (##) Define HAL_ETH_USE_PTP to use PTP APIs.
81 (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef
82 (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef
83 (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers
84 (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers
85 (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers
86 (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission
87 (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp
88 (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp
89
90 -@- The ARP offload feature is not supported in this driver.
91
92 -@- The PTP offload feature is not supported in this driver.
93
94 *** Callback registration ***
95 =============================================
96
97 The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
98 allows the user to configure dynamically the driver callbacks.
99 Use Function HAL_ETH_RegisterCallback() to register an interrupt callback.
100
101 Function HAL_ETH_RegisterCallback() allows to register following callbacks:
102 (+) TxCpltCallback : Tx Complete Callback.
103 (+) RxCpltCallback : Rx Complete Callback.
104 (+) ErrorCallback : Error Callback.
105 (+) PMTCallback : Power Management Callback
106 (+) EEECallback : EEE Callback.
107 (+) WakeUpCallback : Wake UP Callback
108 (+) MspInitCallback : MspInit Callback.
109 (+) MspDeInitCallback: MspDeInit Callback.
110
111 This function takes as parameters the HAL peripheral handle, the Callback ID
112 and a pointer to the user callback function.
113
114 For specific callbacks RxAllocateCallback use dedicated register callbacks:
115 respectively HAL_ETH_RegisterRxAllocateCallback().
116
117 For specific callbacks RxLinkCallback use dedicated register callbacks:
118 respectively HAL_ETH_RegisterRxLinkCallback().
119
120 For specific callbacks TxFreeCallback use dedicated register callbacks:
121 respectively HAL_ETH_RegisterTxFreeCallback().
122
123 For specific callbacks TxPtpCallback use dedicated register callbacks:
124 respectively HAL_ETH_RegisterTxPtpCallback().
125
126 Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default
127 weak function.
128 HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
129 and the Callback ID.
130 This function allows to reset following callbacks:
131 (+) TxCpltCallback : Tx Complete Callback.
132 (+) RxCpltCallback : Rx Complete Callback.
133 (+) ErrorCallback : Error Callback.
134 (+) PMTCallback : Power Management Callback
135 (+) EEECallback : EEE Callback.
136 (+) WakeUpCallback : Wake UP Callback
137 (+) MspInitCallback : MspInit Callback.
138 (+) MspDeInitCallback: MspDeInit Callback.
139
140 For specific callbacks RxAllocateCallback use dedicated unregister callbacks:
141 respectively HAL_ETH_UnRegisterRxAllocateCallback().
142
143 For specific callbacks RxLinkCallback use dedicated unregister callbacks:
144 respectively HAL_ETH_UnRegisterRxLinkCallback().
145
146 For specific callbacks TxFreeCallback use dedicated unregister callbacks:
147 respectively HAL_ETH_UnRegisterTxFreeCallback().
148
149 For specific callbacks TxPtpCallback use dedicated unregister callbacks:
150 respectively HAL_ETH_UnRegisterTxPtpCallback().
151
152 By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
153 all callbacks are set to the corresponding weak functions:
154 examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback().
155 Exception done for MspInit and MspDeInit functions that are
156 reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when
157 these callbacks are null (not registered beforehand).
158 if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit
159 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
160
161 Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
162 Exception done MspInit/MspDeInit that can be registered/unregistered
163 in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
164 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
165 In that case first register the MspInit/MspDeInit user callbacks
166 using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit
167 or HAL_ETH_Init function.
168
169 When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
170 not defined, the callback registration feature is not available and all callbacks
171 are set to the corresponding weak functions.
172
173 @endverbatim
174 ******************************************************************************
175 */
176
177 /* Includes ------------------------------------------------------------------*/
178 #include "stm32h7xx_hal.h"
179
180 /** @addtogroup STM32H7xx_HAL_Driver
181 * @{
182 */
183 #ifdef HAL_ETH_MODULE_ENABLED
184
185 #if defined(ETH)
186
187 /** @defgroup ETH ETH
188 * @brief ETH HAL module driver
189 * @{
190 */
191
192 /* Private typedef -----------------------------------------------------------*/
193 /* Private define ------------------------------------------------------------*/
194 /** @addtogroup ETH_Private_Constants ETH Private Constants
195 * @{
196 */
197 #define ETH_MACCR_MASK 0xFFFB7F7CU
198 #define ETH_MACECR_MASK 0x3F077FFFU
199 #define ETH_MACPFR_MASK 0x800007FFU
200 #define ETH_MACWTR_MASK 0x0000010FU
201 #define ETH_MACTFCR_MASK 0xFFFF00F2U
202 #define ETH_MACRFCR_MASK 0x00000003U
203 #define ETH_MTLTQOMR_MASK 0x00000072U
204 #define ETH_MTLRQOMR_MASK 0x0000007BU
205
206 #define ETH_DMAMR_MASK 0x00007802U
207 #define ETH_DMASBMR_MASK 0x0000D001U
208 #define ETH_DMACCR_MASK 0x00013FFFU
209 #define ETH_DMACTCR_MASK 0x003F1010U
210 #define ETH_DMACRCR_MASK 0x803F0000U
211 #define ETH_MACPCSR_MASK (ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \
212 ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \
213 ETH_MACPCSR_RWKPFE)
214
215 /* Timeout values */
216 #define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t)(ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \
217 ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\
218 ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE))
219
220 #define ETH_MACTSCR_MASK 0x0087FF2FU
221
222 #define ETH_MACSTSUR_VALUE 0xFFFFFFFFU
223 #define ETH_MACSTNUR_VALUE 0xBB9ACA00U
224 #define ETH_SEGMENT_SIZE_DEFAULT 0x218U
225 /**
226 * @}
227 */
228
229 /* Private macros ------------------------------------------------------------*/
230 /** @defgroup ETH_Private_Macros ETH Private Macros
231 * @{
232 */
233 /* Helper macros for TX descriptor handling */
234 #define INCR_TX_DESC_INDEX(inx, offset) do {\
235 (inx) += (offset);\
236 if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\
237 (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\
238 } while (0)
239
240 /* Helper macros for RX descriptor handling */
241 #define INCR_RX_DESC_INDEX(inx, offset) do {\
242 (inx) += (offset);\
243 if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\
244 (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\
245 } while (0)
246 /**
247 * @}
248 */
249 /* Private function prototypes -----------------------------------------------*/
250 /** @defgroup ETH_Private_Functions ETH Private Functions
251 * @{
252 */
253 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf);
254 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf);
255 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth);
256 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth);
257 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth);
258 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
259 uint32_t ItMode);
260 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth);
261
262 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
263 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
264 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
265 /**
266 * @}
267 */
268
269 /* Exported functions ---------------------------------------------------------*/
270 /** @defgroup ETH_Exported_Functions ETH Exported Functions
271 * @{
272 */
273
274 /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions
275 * @brief Initialization and Configuration functions
276 *
277 @verbatim
278 ===============================================================================
279 ##### Initialization and Configuration functions #####
280 ===============================================================================
281 [..] This subsection provides a set of functions allowing to initialize and
282 deinitialize the ETH peripheral:
283
284 (+) User must Implement HAL_ETH_MspInit() function in which he configures
285 all related peripherals resources (CLOCK, GPIO and NVIC ).
286
287 (+) Call the function HAL_ETH_Init() to configure the selected device with
288 the selected configuration:
289 (++) MAC address
290 (++) Media interface (MII or RMII)
291 (++) Rx DMA Descriptors Tab
292 (++) Tx DMA Descriptors Tab
293 (++) Length of Rx Buffers
294
295 (+) Call the function HAL_ETH_DeInit() to restore the default configuration
296 of the selected ETH peripheral.
297
298 @endverbatim
299 * @{
300 */
301
302 /**
303 * @brief Initialize the Ethernet peripheral registers.
304 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
305 * the configuration information for ETHERNET module
306 * @retval HAL status
307 */
HAL_ETH_Init(ETH_HandleTypeDef * heth)308 HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
309 {
310 uint32_t tickstart;
311
312 if (heth == NULL)
313 {
314 return HAL_ERROR;
315 }
316 if (heth->gState == HAL_ETH_STATE_RESET)
317 {
318 heth->gState = HAL_ETH_STATE_BUSY;
319
320 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
321
322 ETH_InitCallbacksToDefault(heth);
323
324 if (heth->MspInitCallback == NULL)
325 {
326 heth->MspInitCallback = HAL_ETH_MspInit;
327 }
328
329 /* Init the low level hardware */
330 heth->MspInitCallback(heth);
331 #else
332 /* Init the low level hardware : GPIO, CLOCK, NVIC. */
333 HAL_ETH_MspInit(heth);
334
335 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
336 }
337
338 __HAL_RCC_SYSCFG_CLK_ENABLE();
339
340 if (heth->Init.MediaInterface == HAL_ETH_MII_MODE)
341 {
342 HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_MII);
343 }
344 else
345 {
346 HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RMII);
347 }
348
349 /* Dummy read to sync with ETH */
350 (void)SYSCFG->PMCR;
351
352 /* Ethernet Software reset */
353 /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
354 /* After reset all the registers holds their respective reset values */
355 SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR);
356
357 /* Get tick */
358 tickstart = HAL_GetTick();
359
360 /* Wait for software reset */
361 while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U)
362 {
363 if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
364 {
365 /* Set Error Code */
366 heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
367 /* Set State as Error */
368 heth->gState = HAL_ETH_STATE_ERROR;
369 /* Return Error */
370 return HAL_ERROR;
371 }
372 }
373
374 /*------------------ MDIO CSR Clock Range Configuration --------------------*/
375 HAL_ETH_SetMDIOClockRange(heth);
376
377 /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/
378 WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U));
379
380 /*------------------ MAC, MTL and DMA default Configuration ----------------*/
381 ETH_MACDMAConfig(heth);
382
383 /* SET DSL to 64 bit */
384 MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT);
385
386 /* Set Receive Buffers Length (must be a multiple of 4) */
387 if ((heth->Init.RxBuffLen % 0x4U) != 0x0U)
388 {
389 /* Set Error Code */
390 heth->ErrorCode = HAL_ETH_ERROR_PARAM;
391 /* Set State as Error */
392 heth->gState = HAL_ETH_STATE_ERROR;
393 /* Return Error */
394 return HAL_ERROR;
395 }
396 else
397 {
398 MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1));
399 }
400
401 /*------------------ DMA Tx Descriptors Configuration ----------------------*/
402 ETH_DMATxDescListInit(heth);
403
404 /*------------------ DMA Rx Descriptors Configuration ----------------------*/
405 ETH_DMARxDescListInit(heth);
406
407 /*--------------------- ETHERNET MAC Address Configuration ------------------*/
408 /* Set MAC addr bits 32 to 47 */
409 heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]);
410 /* Set MAC addr bits 0 to 31 */
411 heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) |
412 ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]);
413
414 /* Disable Rx MMC Interrupts */
415 SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \
416 ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM);
417
418 /* Disable Tx MMC Interrupts */
419 SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \
420 ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM);
421
422 heth->ErrorCode = HAL_ETH_ERROR_NONE;
423 heth->gState = HAL_ETH_STATE_READY;
424
425 return HAL_OK;
426 }
427
428 /**
429 * @brief DeInitializes the ETH peripheral.
430 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
431 * the configuration information for ETHERNET module
432 * @retval HAL status
433 */
HAL_ETH_DeInit(ETH_HandleTypeDef * heth)434 HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
435 {
436 /* Set the ETH peripheral state to BUSY */
437 heth->gState = HAL_ETH_STATE_BUSY;
438
439 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
440
441 if (heth->MspDeInitCallback == NULL)
442 {
443 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
444 }
445 /* DeInit the low level hardware */
446 heth->MspDeInitCallback(heth);
447 #else
448
449 /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
450 HAL_ETH_MspDeInit(heth);
451
452 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
453
454 /* Set ETH HAL state to Disabled */
455 heth->gState = HAL_ETH_STATE_RESET;
456
457 /* Return function status */
458 return HAL_OK;
459 }
460
461 /**
462 * @brief Initializes the ETH MSP.
463 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
464 * the configuration information for ETHERNET module
465 * @retval None
466 */
HAL_ETH_MspInit(ETH_HandleTypeDef * heth)467 __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
468 {
469 /* Prevent unused argument(s) compilation warning */
470 UNUSED(heth);
471 /* NOTE : This function Should not be modified, when the callback is needed,
472 the HAL_ETH_MspInit could be implemented in the user file
473 */
474 }
475
476 /**
477 * @brief DeInitializes ETH MSP.
478 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
479 * the configuration information for ETHERNET module
480 * @retval None
481 */
HAL_ETH_MspDeInit(ETH_HandleTypeDef * heth)482 __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
483 {
484 /* Prevent unused argument(s) compilation warning */
485 UNUSED(heth);
486 /* NOTE : This function Should not be modified, when the callback is needed,
487 the HAL_ETH_MspDeInit could be implemented in the user file
488 */
489 }
490
491 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
492 /**
493 * @brief Register a User ETH Callback
494 * To be used instead of the weak predefined callback
495 * @param heth eth handle
496 * @param CallbackID ID of the callback to be registered
497 * This parameter can be one of the following values:
498 * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
499 * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
500 * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID
501 * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID
502 * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID
503 * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID
504 * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID
505 * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID
506 * @param pCallback pointer to the Callback function
507 * @retval status
508 */
HAL_ETH_RegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID,pETH_CallbackTypeDef pCallback)509 HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID,
510 pETH_CallbackTypeDef pCallback)
511 {
512 HAL_StatusTypeDef status = HAL_OK;
513
514 if (pCallback == NULL)
515 {
516 /* Update the error code */
517 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
518 return HAL_ERROR;
519 }
520
521 if (heth->gState == HAL_ETH_STATE_READY)
522 {
523 switch (CallbackID)
524 {
525 case HAL_ETH_TX_COMPLETE_CB_ID :
526 heth->TxCpltCallback = pCallback;
527 break;
528
529 case HAL_ETH_RX_COMPLETE_CB_ID :
530 heth->RxCpltCallback = pCallback;
531 break;
532
533 case HAL_ETH_ERROR_CB_ID :
534 heth->ErrorCallback = pCallback;
535 break;
536
537 case HAL_ETH_PMT_CB_ID :
538 heth->PMTCallback = pCallback;
539 break;
540
541 case HAL_ETH_EEE_CB_ID :
542 heth->EEECallback = pCallback;
543 break;
544
545 case HAL_ETH_WAKEUP_CB_ID :
546 heth->WakeUpCallback = pCallback;
547 break;
548
549 case HAL_ETH_MSPINIT_CB_ID :
550 heth->MspInitCallback = pCallback;
551 break;
552
553 case HAL_ETH_MSPDEINIT_CB_ID :
554 heth->MspDeInitCallback = pCallback;
555 break;
556
557 default :
558 /* Update the error code */
559 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
560 /* Return error status */
561 status = HAL_ERROR;
562 break;
563 }
564 }
565 else if (heth->gState == HAL_ETH_STATE_RESET)
566 {
567 switch (CallbackID)
568 {
569 case HAL_ETH_MSPINIT_CB_ID :
570 heth->MspInitCallback = pCallback;
571 break;
572
573 case HAL_ETH_MSPDEINIT_CB_ID :
574 heth->MspDeInitCallback = pCallback;
575 break;
576
577 default :
578 /* Update the error code */
579 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
580 /* Return error status */
581 status = HAL_ERROR;
582 break;
583 }
584 }
585 else
586 {
587 /* Update the error code */
588 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
589 /* Return error status */
590 status = HAL_ERROR;
591 }
592
593 return status;
594 }
595
596 /**
597 * @brief Unregister an ETH Callback
598 * ETH callback is redirected to the weak predefined callback
599 * @param heth eth handle
600 * @param CallbackID ID of the callback to be unregistered
601 * This parameter can be one of the following values:
602 * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
603 * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
604 * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID
605 * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID
606 * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID
607 * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID
608 * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID
609 * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID
610 * @retval status
611 */
HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID)612 HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
613 {
614 HAL_StatusTypeDef status = HAL_OK;
615
616 if (heth->gState == HAL_ETH_STATE_READY)
617 {
618 switch (CallbackID)
619 {
620 case HAL_ETH_TX_COMPLETE_CB_ID :
621 heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
622 break;
623
624 case HAL_ETH_RX_COMPLETE_CB_ID :
625 heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
626 break;
627
628 case HAL_ETH_ERROR_CB_ID :
629 heth->ErrorCallback = HAL_ETH_ErrorCallback;
630 break;
631
632 case HAL_ETH_PMT_CB_ID :
633 heth->PMTCallback = HAL_ETH_PMTCallback;
634 break;
635
636 case HAL_ETH_EEE_CB_ID :
637 heth->EEECallback = HAL_ETH_EEECallback;
638 break;
639
640 case HAL_ETH_WAKEUP_CB_ID :
641 heth->WakeUpCallback = HAL_ETH_WakeUpCallback;
642 break;
643
644 case HAL_ETH_MSPINIT_CB_ID :
645 heth->MspInitCallback = HAL_ETH_MspInit;
646 break;
647
648 case HAL_ETH_MSPDEINIT_CB_ID :
649 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
650 break;
651
652 default :
653 /* Update the error code */
654 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
655 /* Return error status */
656 status = HAL_ERROR;
657 break;
658 }
659 }
660 else if (heth->gState == HAL_ETH_STATE_RESET)
661 {
662 switch (CallbackID)
663 {
664 case HAL_ETH_MSPINIT_CB_ID :
665 heth->MspInitCallback = HAL_ETH_MspInit;
666 break;
667
668 case HAL_ETH_MSPDEINIT_CB_ID :
669 heth->MspDeInitCallback = HAL_ETH_MspDeInit;
670 break;
671
672 default :
673 /* Update the error code */
674 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
675 /* Return error status */
676 status = HAL_ERROR;
677 break;
678 }
679 }
680 else
681 {
682 /* Update the error code */
683 heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
684 /* Return error status */
685 status = HAL_ERROR;
686 }
687
688 return status;
689 }
690 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
691
692 /**
693 * @}
694 */
695
696 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
697 * @brief ETH Transmit and Receive functions
698 *
699 @verbatim
700 ==============================================================================
701 ##### IO operation functions #####
702 ==============================================================================
703 [..]
704 This subsection provides a set of functions allowing to manage the ETH
705 data transfer.
706
707 @endverbatim
708 * @{
709 */
710
711 /**
712 * @brief Enables Ethernet MAC and DMA reception and transmission
713 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
714 * the configuration information for ETHERNET module
715 * @retval HAL status
716 */
HAL_ETH_Start(ETH_HandleTypeDef * heth)717 HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
718 {
719 if (heth->gState == HAL_ETH_STATE_READY)
720 {
721 heth->gState = HAL_ETH_STATE_BUSY;
722
723 /* Set number of descriptors to build */
724 heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
725
726 /* Build all descriptors */
727 ETH_UpdateDescriptor(heth);
728
729 /* Enable the MAC transmission */
730 SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
731
732 /* Enable the MAC reception */
733 SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
734
735 /* Set the Flush Transmit FIFO bit */
736 SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
737
738 /* Enable the DMA transmission */
739 SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
740
741 /* Enable the DMA reception */
742 SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
743
744 /* Clear Tx and Rx process stopped flags */
745 heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS);
746
747 heth->gState = HAL_ETH_STATE_STARTED;
748
749 return HAL_OK;
750 }
751 else
752 {
753 return HAL_ERROR;
754 }
755 }
756
757 /**
758 * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode
759 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
760 * the configuration information for ETHERNET module
761 * @retval HAL status
762 */
HAL_ETH_Start_IT(ETH_HandleTypeDef * heth)763 HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
764 {
765 if (heth->gState == HAL_ETH_STATE_READY)
766 {
767 heth->gState = HAL_ETH_STATE_BUSY;
768
769 /* save IT mode to ETH Handle */
770 heth->RxDescList.ItMode = 1U;
771
772 /* Set number of descriptors to build */
773 heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
774
775 /* Build all descriptors */
776 ETH_UpdateDescriptor(heth);
777
778 /* Enable the DMA transmission */
779 SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
780
781 /* Enable the DMA reception */
782 SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
783
784 /* Clear Tx and Rx process stopped flags */
785 heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS);
786
787 /* Set the Flush Transmit FIFO bit */
788 SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
789
790 /* Enable the MAC transmission */
791 SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
792
793 /* Enable the MAC reception */
794 SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
795
796 /* Enable ETH DMA interrupts:
797 - Tx complete interrupt
798 - Rx complete interrupt
799 - Fatal bus interrupt
800 */
801 __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE |
802 ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE));
803
804 heth->gState = HAL_ETH_STATE_STARTED;
805 return HAL_OK;
806 }
807 else
808 {
809 return HAL_ERROR;
810 }
811 }
812
813 /**
814 * @brief Stop Ethernet MAC and DMA reception/transmission
815 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
816 * the configuration information for ETHERNET module
817 * @retval HAL status
818 */
HAL_ETH_Stop(ETH_HandleTypeDef * heth)819 HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
820 {
821 if (heth->gState == HAL_ETH_STATE_STARTED)
822 {
823 /* Set the ETH peripheral state to BUSY */
824 heth->gState = HAL_ETH_STATE_BUSY;
825
826 /* Disable the DMA transmission */
827 CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
828
829 /* Disable the DMA reception */
830 CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
831
832 /* Disable the MAC reception */
833 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
834
835 /* Set the Flush Transmit FIFO bit */
836 SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
837
838 /* Disable the MAC transmission */
839 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
840
841 heth->gState = HAL_ETH_STATE_READY;
842
843 /* Return function status */
844 return HAL_OK;
845 }
846 else
847 {
848 return HAL_ERROR;
849 }
850 }
851
852 /**
853 * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode
854 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
855 * the configuration information for ETHERNET module
856 * @retval HAL status
857 */
HAL_ETH_Stop_IT(ETH_HandleTypeDef * heth)858 HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth)
859 {
860 ETH_DMADescTypeDef *dmarxdesc;
861 uint32_t descindex;
862
863 if (heth->gState == HAL_ETH_STATE_STARTED)
864 {
865 /* Set the ETH peripheral state to BUSY */
866 heth->gState = HAL_ETH_STATE_BUSY;
867
868 /* Disable interrupts:
869 - Tx complete interrupt
870 - Rx complete interrupt
871 - Fatal bus interrupt
872 */
873 __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE |
874 ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE));
875
876 /* Disable the DMA transmission */
877 CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
878
879 /* Disable the DMA reception */
880 CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
881
882 /* Disable the MAC reception */
883 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
884
885 /* Set the Flush Transmit FIFO bit */
886 SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
887
888 /* Disable the MAC transmission */
889 CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
890
891 /* Clear IOC bit to all Rx descriptors */
892 for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
893 {
894 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex];
895 CLEAR_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC);
896 }
897
898 heth->RxDescList.ItMode = 0U;
899
900 heth->gState = HAL_ETH_STATE_READY;
901
902 /* Return function status */
903 return HAL_OK;
904 }
905 else
906 {
907 return HAL_ERROR;
908 }
909 }
910
911 /**
912 * @brief Sends an Ethernet Packet in polling mode.
913 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
914 * the configuration information for ETHERNET module
915 * @param pTxConfig: Hold the configuration of packet to be transmitted
916 * @param Timeout: timeout value
917 * @retval HAL status
918 */
HAL_ETH_Transmit(ETH_HandleTypeDef * heth,ETH_TxPacketConfigTypeDef * pTxConfig,uint32_t Timeout)919 HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout)
920 {
921 uint32_t tickstart;
922 ETH_DMADescTypeDef *dmatxdesc;
923
924 if (pTxConfig == NULL)
925 {
926 heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
927 return HAL_ERROR;
928 }
929
930 if (heth->gState == HAL_ETH_STATE_STARTED)
931 {
932 /* Config DMA Tx descriptor by Tx Packet info */
933 if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE)
934 {
935 /* Set the ETH error code */
936 heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
937 return HAL_ERROR;
938 }
939
940 /* Ensure completion of descriptor preparation before transmission start */
941 __DSB();
942
943 dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc];
944
945 /* Incr current tx desc index */
946 INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
947
948 /* Start transmission */
949 /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
950 WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
951
952 tickstart = HAL_GetTick();
953
954 /* Wait for data to be transmitted or timeout occurred */
955 while ((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET)
956 {
957 if ((heth->Instance->DMACSR & ETH_DMACSR_FBE) != (uint32_t)RESET)
958 {
959 heth->ErrorCode |= HAL_ETH_ERROR_DMA;
960 heth->DMAErrorCode = heth->Instance->DMACSR;
961 /* Return function status */
962 return HAL_ERROR;
963 }
964
965 /* Check for the Timeout */
966 if (Timeout != HAL_MAX_DELAY)
967 {
968 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
969 {
970 heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT;
971 /* Clear TX descriptor so that we can proceed */
972 dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD);
973 return HAL_ERROR;
974 }
975 }
976 }
977
978 /* Return function status */
979 return HAL_OK;
980 }
981 else
982 {
983 return HAL_ERROR;
984 }
985 }
986
987 /**
988 * @brief Sends an Ethernet Packet in interrupt mode.
989 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
990 * the configuration information for ETHERNET module
991 * @param pTxConfig: Hold the configuration of packet to be transmitted
992 * @retval HAL status
993 */
HAL_ETH_Transmit_IT(ETH_HandleTypeDef * heth,ETH_TxPacketConfigTypeDef * pTxConfig)994 HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig)
995 {
996 if (pTxConfig == NULL)
997 {
998 heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
999 return HAL_ERROR;
1000 }
1001
1002 if (heth->gState == HAL_ETH_STATE_STARTED)
1003 {
1004 /* Save the packet pointer to release. */
1005 heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData;
1006
1007 /* Config DMA Tx descriptor by Tx Packet info */
1008 if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE)
1009 {
1010 heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
1011 return HAL_ERROR;
1012 }
1013
1014 /* Ensure completion of descriptor preparation before transmission start */
1015 __DSB();
1016
1017 /* Incr current tx desc index */
1018 INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
1019
1020 /* Start transmission */
1021 /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
1022 WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
1023
1024 return HAL_OK;
1025
1026 }
1027 else
1028 {
1029 return HAL_ERROR;
1030 }
1031 }
1032
1033 /**
1034 * @brief Read a received packet.
1035 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1036 * the configuration information for ETHERNET module
1037 * @param pAppBuff: Pointer to an application buffer to receive the packet.
1038 * @retval HAL status
1039 */
HAL_ETH_ReadData(ETH_HandleTypeDef * heth,void ** pAppBuff)1040 HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
1041 {
1042 uint32_t descidx, descidx_temp;
1043 ETH_DMADescTypeDef *dmarxdesc, *dmarxdesc_temp;
1044 uint32_t desccnt = 0U;
1045 uint32_t desccntmax;
1046 uint32_t bufflength;
1047 uint8_t rxdataready = 0U;
1048
1049 if (pAppBuff == NULL)
1050 {
1051 heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1052 return HAL_ERROR;
1053 }
1054
1055 if (heth->gState != HAL_ETH_STATE_STARTED)
1056 {
1057 return HAL_ERROR;
1058 }
1059
1060 descidx = heth->RxDescList.RxDescIdx;
1061 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1062 desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt;
1063
1064 /* Check if descriptor is not owned by DMA */
1065 while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax)
1066 && (rxdataready == 0U))
1067 {
1068 if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL))
1069 {
1070 /* Check if first descriptor */
1071 if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET)
1072 {
1073 heth->RxDescList.RxDescCnt = 0;
1074 heth->RxDescList.RxDataLength = 0;
1075 }
1076
1077 /* Get the Frame Length of the received packet */
1078 bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength;
1079
1080 /* Check if last descriptor */
1081 if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET)
1082 {
1083 /* Save Last descriptor index */
1084 heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3;
1085
1086 /* Packet ready */
1087 rxdataready = 1;
1088
1089 if (READ_BIT(dmarxdesc->DESC1, ETH_DMARXNDESCWBF_TSA) != (uint32_t)RESET)
1090 {
1091 descidx_temp = descidx;
1092 INCR_RX_DESC_INDEX(descidx_temp, 1U);
1093
1094 dmarxdesc_temp = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx_temp];
1095
1096 if (READ_BIT(dmarxdesc_temp->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET)
1097 {
1098 /* Get timestamp high */
1099 heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc_temp->DESC1;
1100 /* Get timestamp low */
1101 heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc_temp->DESC0;
1102 }
1103 }
1104 }
1105
1106 /* Link data */
1107 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1108 /*Call registered Link callback*/
1109 heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1110 (uint8_t *)dmarxdesc->BackupAddr0, bufflength);
1111 #else
1112 /* Link callback */
1113 HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1114 (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength);
1115 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1116 heth->RxDescList.RxDescCnt++;
1117 heth->RxDescList.RxDataLength += bufflength;
1118
1119 /* Clear buffer pointer */
1120 dmarxdesc->BackupAddr0 = 0;
1121 }
1122
1123 /* Increment current rx descriptor index */
1124 INCR_RX_DESC_INDEX(descidx, 1U);
1125 /* Get current descriptor address */
1126 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1127 desccnt++;
1128 }
1129
1130 heth->RxDescList.RxBuildDescCnt += desccnt;
1131 if ((heth->RxDescList.RxBuildDescCnt) != 0U)
1132 {
1133 /* Update Descriptors */
1134 ETH_UpdateDescriptor(heth);
1135 }
1136
1137 heth->RxDescList.RxDescIdx = descidx;
1138
1139 if (rxdataready == 1U)
1140 {
1141 /* Return received packet */
1142 *pAppBuff = heth->RxDescList.pRxStart;
1143 /* Reset first element */
1144 heth->RxDescList.pRxStart = NULL;
1145
1146 return HAL_OK;
1147 }
1148
1149 /* Packet not ready */
1150 return HAL_ERROR;
1151 }
1152
1153 /**
1154 * @brief This function gives back Rx Desc of the last received Packet
1155 * to the DMA, so ETH DMA will be able to use these descriptors
1156 * to receive next Packets.
1157 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1158 * the configuration information for ETHERNET module
1159 * @retval HAL status
1160 */
ETH_UpdateDescriptor(ETH_HandleTypeDef * heth)1161 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth)
1162 {
1163 uint32_t descidx;
1164 uint32_t tailidx;
1165 uint32_t desccount;
1166 ETH_DMADescTypeDef *dmarxdesc;
1167 uint8_t *buff = NULL;
1168 uint8_t allocStatus = 1U;
1169
1170 descidx = heth->RxDescList.RxBuildDescIdx;
1171 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1172 desccount = heth->RxDescList.RxBuildDescCnt;
1173
1174 while ((desccount > 0U) && (allocStatus != 0U))
1175 {
1176 /* Check if a buffer's attached the descriptor */
1177 if (READ_REG(dmarxdesc->BackupAddr0) == 0U)
1178 {
1179 /* Get a new buffer. */
1180 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1181 /*Call registered Allocate callback*/
1182 heth->rxAllocateCallback(&buff);
1183 #else
1184 /* Allocate callback */
1185 HAL_ETH_RxAllocateCallback(&buff);
1186 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1187 if (buff == NULL)
1188 {
1189 allocStatus = 0U;
1190 }
1191 else
1192 {
1193 WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff);
1194 WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff);
1195 }
1196 }
1197
1198 if (allocStatus != 0U)
1199 {
1200
1201 if (heth->RxDescList.ItMode != 0U)
1202 {
1203 WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC);
1204 }
1205 else
1206 {
1207 WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V);
1208 }
1209
1210 /* Increment current rx descriptor index */
1211 INCR_RX_DESC_INDEX(descidx, 1U);
1212 /* Get current descriptor address */
1213 dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1214 desccount--;
1215 }
1216 }
1217
1218 if (heth->RxDescList.RxBuildDescCnt != desccount)
1219 {
1220 /* Set the tail pointer index */
1221 tailidx = (ETH_RX_DESC_CNT + descidx - 1U) % ETH_RX_DESC_CNT;
1222
1223 /* DMB instruction to avoid race condition */
1224 __DMB();
1225
1226 /* Set the Tail pointer address */
1227 WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (tailidx))));
1228
1229 heth->RxDescList.RxBuildDescIdx = descidx;
1230 heth->RxDescList.RxBuildDescCnt = desccount;
1231 }
1232 }
1233
1234 /**
1235 * @brief Register the Rx alloc callback.
1236 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1237 * the configuration information for ETHERNET module
1238 * @param rxAllocateCallback: pointer to function to alloc buffer
1239 * @retval HAL status
1240 */
HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef * heth,pETH_rxAllocateCallbackTypeDef rxAllocateCallback)1241 HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth,
1242 pETH_rxAllocateCallbackTypeDef rxAllocateCallback)
1243 {
1244 if (rxAllocateCallback == NULL)
1245 {
1246 /* No buffer to save */
1247 return HAL_ERROR;
1248 }
1249
1250 /* Set function to allocate buffer */
1251 heth->rxAllocateCallback = rxAllocateCallback;
1252
1253 return HAL_OK;
1254 }
1255
1256 /**
1257 * @brief Unregister the Rx alloc callback.
1258 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1259 * the configuration information for ETHERNET module
1260 * @retval HAL status
1261 */
HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef * heth)1262 HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth)
1263 {
1264 /* Set function to allocate buffer */
1265 heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback;
1266
1267 return HAL_OK;
1268 }
1269
1270 /**
1271 * @brief Rx Allocate callback.
1272 * @param buff: pointer to allocated buffer
1273 * @retval None
1274 */
HAL_ETH_RxAllocateCallback(uint8_t ** buff)1275 __weak void HAL_ETH_RxAllocateCallback(uint8_t **buff)
1276 {
1277 /* Prevent unused argument(s) compilation warning */
1278 UNUSED(buff);
1279 /* NOTE : This function Should not be modified, when the callback is needed,
1280 the HAL_ETH_RxAllocateCallback could be implemented in the user file
1281 */
1282 }
1283
1284 /**
1285 * @brief Rx Link callback.
1286 * @param pStart: pointer to packet start
1287 * @param pEnd: pointer to packet end
1288 * @param buff: pointer to received data
1289 * @param Length: received data length
1290 * @retval None
1291 */
HAL_ETH_RxLinkCallback(void ** pStart,void ** pEnd,uint8_t * buff,uint16_t Length)1292 __weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
1293 {
1294 /* Prevent unused argument(s) compilation warning */
1295 UNUSED(pStart);
1296 UNUSED(pEnd);
1297 UNUSED(buff);
1298 UNUSED(Length);
1299 /* NOTE : This function Should not be modified, when the callback is needed,
1300 the HAL_ETH_RxLinkCallback could be implemented in the user file
1301 */
1302 }
1303
1304 /**
1305 * @brief Set the Rx link data function.
1306 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1307 * the configuration information for ETHERNET module
1308 * @param rxLinkCallback: pointer to function to link data
1309 * @retval HAL status
1310 */
HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef * heth,pETH_rxLinkCallbackTypeDef rxLinkCallback)1311 HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback)
1312 {
1313 if (rxLinkCallback == NULL)
1314 {
1315 /* No buffer to save */
1316 return HAL_ERROR;
1317 }
1318
1319 /* Set function to link data */
1320 heth->rxLinkCallback = rxLinkCallback;
1321
1322 return HAL_OK;
1323 }
1324
1325 /**
1326 * @brief Unregister the Rx link callback.
1327 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1328 * the configuration information for ETHERNET module
1329 * @retval HAL status
1330 */
HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef * heth)1331 HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth)
1332 {
1333 /* Set function to allocate buffer */
1334 heth->rxLinkCallback = HAL_ETH_RxLinkCallback;
1335
1336 return HAL_OK;
1337 }
1338
1339 /**
1340 * @brief Get the error state of the last received packet.
1341 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1342 * the configuration information for ETHERNET module
1343 * @param pErrorCode: pointer to uint32_t to hold the error code
1344 * @retval HAL status
1345 */
HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef * heth,uint32_t * pErrorCode)1346 HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode)
1347 {
1348 /* Get error bits. */
1349 *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK);
1350
1351 return HAL_OK;
1352 }
1353
1354 /**
1355 * @brief Set the Tx free function.
1356 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1357 * the configuration information for ETHERNET module
1358 * @param txFreeCallback: pointer to function to release the packet
1359 * @retval HAL status
1360 */
HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef * heth,pETH_txFreeCallbackTypeDef txFreeCallback)1361 HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback)
1362 {
1363 if (txFreeCallback == NULL)
1364 {
1365 /* No buffer to save */
1366 return HAL_ERROR;
1367 }
1368
1369 /* Set function to free transmmitted packet */
1370 heth->txFreeCallback = txFreeCallback;
1371
1372 return HAL_OK;
1373 }
1374
1375 /**
1376 * @brief Unregister the Tx free callback.
1377 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1378 * the configuration information for ETHERNET module
1379 * @retval HAL status
1380 */
HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef * heth)1381 HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth)
1382 {
1383 /* Set function to allocate buffer */
1384 heth->txFreeCallback = HAL_ETH_TxFreeCallback;
1385
1386 return HAL_OK;
1387 }
1388
1389 /**
1390 * @brief Tx Free callback.
1391 * @param buff: pointer to buffer to free
1392 * @retval None
1393 */
HAL_ETH_TxFreeCallback(uint32_t * buff)1394 __weak void HAL_ETH_TxFreeCallback(uint32_t *buff)
1395 {
1396 /* Prevent unused argument(s) compilation warning */
1397 UNUSED(buff);
1398 /* NOTE : This function Should not be modified, when the callback is needed,
1399 the HAL_ETH_TxFreeCallback could be implemented in the user file
1400 */
1401 }
1402
1403 /**
1404 * @brief Release transmitted Tx packets.
1405 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1406 * the configuration information for ETHERNET module
1407 * @retval HAL status
1408 */
HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef * heth)1409 HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth)
1410 {
1411 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1412 uint32_t numOfBuf = dmatxdesclist->BuffersInUse;
1413 uint32_t idx = dmatxdesclist->releaseIndex;
1414 uint8_t pktTxStatus = 1U;
1415 uint8_t pktInUse;
1416 #ifdef HAL_ETH_USE_PTP
1417 ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp;
1418 #endif /* HAL_ETH_USE_PTP */
1419
1420 /* Loop through buffers in use. */
1421 while ((numOfBuf != 0U) && (pktTxStatus != 0U))
1422 {
1423 pktInUse = 1U;
1424 numOfBuf--;
1425 /* If no packet, just examine the next packet. */
1426 if (dmatxdesclist->PacketAddress[idx] == NULL)
1427 {
1428 /* No packet in use, skip to next. */
1429 INCR_TX_DESC_INDEX(idx, 1U);
1430 pktInUse = 0U;
1431 }
1432
1433 if (pktInUse != 0U)
1434 {
1435 /* Determine if the packet has been transmitted. */
1436 if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U)
1437 {
1438 #ifdef HAL_ETH_USE_PTP
1439
1440 /* Disable Ptp transmission */
1441 CLEAR_BIT(heth->Init.TxDesc[idx].DESC2, ETH_DMATXNDESCRF_TTSE);
1442
1443 if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_LD)
1444 && (heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_TTSS))
1445 {
1446 /* Get timestamp low */
1447 timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0;
1448 /* Get timestamp high */
1449 timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1;
1450 }
1451 else
1452 {
1453 timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX;
1454 }
1455 #endif /* HAL_ETH_USE_PTP */
1456
1457 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1458 /*Call registered callbacks*/
1459 #ifdef HAL_ETH_USE_PTP
1460 /* Handle Ptp */
1461 if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1462 {
1463 heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1464 }
1465 #endif /* HAL_ETH_USE_PTP */
1466 /* Release the packet. */
1467 heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
1468 #else
1469 /* Call callbacks */
1470 #ifdef HAL_ETH_USE_PTP
1471 /* Handle Ptp */
1472 if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1473 {
1474 HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1475 }
1476 #endif /* HAL_ETH_USE_PTP */
1477 /* Release the packet. */
1478 HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
1479 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1480
1481 /* Clear the entry in the in-use array. */
1482 dmatxdesclist->PacketAddress[idx] = NULL;
1483
1484 /* Update the transmit relesae index and number of buffers in use. */
1485 INCR_TX_DESC_INDEX(idx, 1U);
1486 dmatxdesclist->BuffersInUse = numOfBuf;
1487 dmatxdesclist->releaseIndex = idx;
1488 }
1489 else
1490 {
1491 /* Get out of the loop! */
1492 pktTxStatus = 0U;
1493 }
1494 }
1495 }
1496 return HAL_OK;
1497 }
1498
1499 #ifdef HAL_ETH_USE_PTP
1500 /**
1501 * @brief Set the Ethernet PTP configuration.
1502 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1503 * the configuration information for ETHERNET module
1504 * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1505 * the configuration information for PTP
1506 * @retval HAL status
1507 */
HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1508 HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1509 {
1510 uint32_t tmpTSCR;
1511 ETH_TimeTypeDef time;
1512
1513 if (ptpconfig == NULL)
1514 {
1515 return HAL_ERROR;
1516 }
1517
1518 /* Mask the Timestamp Trigger interrupt */
1519 CLEAR_BIT(heth->Instance->MACIER, ETH_MACIER_TSIE);
1520
1521 tmpTSCR = ptpconfig->Timestamp |
1522 ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) |
1523 ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) |
1524 ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) |
1525 ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) |
1526 ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) |
1527 ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) |
1528 ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) |
1529 ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) |
1530 ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) |
1531 ((uint32_t)ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos) |
1532 ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) |
1533 ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos) |
1534 ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos);
1535
1536 /* Write to MACTSCR */
1537 MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR);
1538
1539 /* Enable Timestamp */
1540 SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1541 WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc);
1542 WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend);
1543
1544 /* Enable Timestamp */
1545 if (ptpconfig->TimestampAddendUpdate == ENABLE)
1546 {
1547 SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG);
1548 while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0)
1549 {
1550
1551 }
1552 }
1553
1554 /* Enable Update mode */
1555 if (ptpconfig->TimestampUpdateMode == ENABLE)
1556 {
1557 SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCFUPDT);
1558 }
1559
1560 /* Set PTP Configuration done */
1561 heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED;
1562
1563 /* Set Seconds */
1564 time.Seconds = heth->Instance->MACSTSR;
1565 /* Set NanoSeconds */
1566 time.NanoSeconds = heth->Instance->MACSTNR;
1567
1568 HAL_ETH_PTP_SetTime(heth, &time);
1569
1570 /* Ptp Init */
1571 SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT);
1572
1573 /* Return function status */
1574 return HAL_OK;
1575 }
1576
1577 /**
1578 * @brief Get the Ethernet PTP configuration.
1579 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1580 * the configuration information for ETHERNET module
1581 * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1582 * the configuration information for PTP
1583 * @retval HAL status
1584 */
HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1585 HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1586 {
1587 if (ptpconfig == NULL)
1588 {
1589 return HAL_ERROR;
1590 }
1591 ptpconfig->Timestamp = READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1592 ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR,
1593 ETH_MACTSCR_TSCFUPDT) >> ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE;
1594 ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR,
1595 ETH_MACTSCR_TSENALL) >> ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE;
1596 ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR,
1597 ETH_MACTSCR_TSCTRLSSR) >> ETH_MACTSCR_TSCTRLSSR_Pos) > 0U)
1598 ? ENABLE : DISABLE;
1599 ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR,
1600 ETH_MACTSCR_TSVER2ENA) >> ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE;
1601 ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR,
1602 ETH_MACTSCR_TSIPENA) >> ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE;
1603 ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR,
1604 ETH_MACTSCR_TSIPV6ENA) >> ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE;
1605 ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR,
1606 ETH_MACTSCR_TSIPV4ENA) >> ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE;
1607 ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR,
1608 ETH_MACTSCR_TSEVNTENA) >> ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE;
1609 ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR,
1610 ETH_MACTSCR_TSMSTRENA) >> ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE;
1611 ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR,
1612 ETH_MACTSCR_SNAPTYPSEL) >> ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U)
1613 ? ENABLE : DISABLE;
1614 ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR,
1615 ETH_MACTSCR_TSENMACADDR) >> ETH_MACTSCR_TSENMACADDR_Pos) > 0U)
1616 ? ENABLE : DISABLE;
1617 ptpconfig->TimestampChecksumCorrection = ((READ_BIT(heth->Instance->MACTSCR,
1618 ETH_MACTSCR_CSC) >> ETH_MACTSCR_CSC_Pos) > 0U) ? ENABLE : DISABLE;
1619 ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR,
1620 ETH_MACTSCR_TXTSSTSM) >> ETH_MACTSCR_TXTSSTSM_Pos) > 0U)
1621 ? ENABLE : DISABLE;
1622
1623 /* Return function status */
1624 return HAL_OK;
1625 }
1626
1627 /**
1628 * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers.
1629 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1630 * the configuration information for ETHERNET module
1631 * @param time: pointer to a ETH_TimeTypeDef structure that contains
1632 * time to set
1633 * @retval HAL status
1634 */
HAL_ETH_PTP_SetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1635 HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1636 {
1637 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1638 {
1639 /* Set Seconds */
1640 heth->Instance->MACSTSUR = time->Seconds;
1641
1642 /* Set NanoSeconds */
1643 heth->Instance->MACSTNUR = time->NanoSeconds;
1644
1645 /* the system time is updated */
1646 SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT);
1647
1648 /* Return function status */
1649 return HAL_OK;
1650 }
1651 else
1652 {
1653 /* Return function status */
1654 return HAL_ERROR;
1655 }
1656 }
1657
1658 /**
1659 * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers.
1660 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1661 * the configuration information for ETHERNET module
1662 * @param time: pointer to a ETH_TimeTypeDef structure that contains
1663 * time to get
1664 * @retval HAL status
1665 */
HAL_ETH_PTP_GetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1666 HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1667 {
1668 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1669 {
1670 /* Get Seconds */
1671 time->Seconds = heth->Instance->MACSTSR;
1672 /* Get NanoSeconds */
1673 time->NanoSeconds = heth->Instance->MACSTNR;
1674
1675 /* Return function status */
1676 return HAL_OK;
1677 }
1678 else
1679 {
1680 /* Return function status */
1681 return HAL_ERROR;
1682 }
1683 }
1684
1685 /**
1686 * @brief Update time for the Ethernet PTP registers.
1687 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1688 * the configuration information for ETHERNET module
1689 * @param timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains
1690 * the time update information
1691 * @retval HAL status
1692 */
HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef * heth,ETH_PtpUpdateTypeDef ptpoffsettype,ETH_TimeTypeDef * timeoffset)1693 HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
1694 ETH_TimeTypeDef *timeoffset)
1695 {
1696 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1697 {
1698 if (ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE)
1699 {
1700 /* Set Seconds update */
1701 heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U;
1702
1703 if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR)
1704 {
1705 /* Set nanoSeconds update */
1706 heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds;
1707 }
1708 else
1709 {
1710 /* Set nanoSeconds update */
1711 heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U;
1712 }
1713 }
1714 else
1715 {
1716 /* Set Seconds update */
1717 heth->Instance->MACSTSUR = timeoffset->Seconds;
1718 /* Set nanoSeconds update */
1719 heth->Instance->MACSTNUR = timeoffset->NanoSeconds;
1720 }
1721
1722 SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT);
1723
1724 /* Return function status */
1725 return HAL_OK;
1726 }
1727 else
1728 {
1729 /* Return function status */
1730 return HAL_ERROR;
1731 }
1732 }
1733
1734 /**
1735 * @brief Insert Timestamp in transmission.
1736 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1737 * the configuration information for ETHERNET module
1738 * @retval HAL status
1739 */
HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef * heth)1740 HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
1741 {
1742 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1743 uint32_t descidx = dmatxdesclist->CurTxDesc;
1744 ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
1745
1746 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1747 {
1748 /* Enable Time Stamp transmission */
1749 SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE);
1750
1751 /* Return function status */
1752 return HAL_OK;
1753 }
1754 else
1755 {
1756 /* Return function status */
1757 return HAL_ERROR;
1758 }
1759 }
1760
1761 /**
1762 * @brief Get transmission timestamp.
1763 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1764 * the configuration information for ETHERNET module
1765 * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1766 * transmission timestamp
1767 * @retval HAL status
1768 */
HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1769 HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1770 {
1771 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1772 uint32_t idx = dmatxdesclist->releaseIndex;
1773 ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
1774
1775 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1776 {
1777 /* Get timestamp low */
1778 timestamp->TimeStampLow = dmatxdesc->DESC0;
1779 /* Get timestamp high */
1780 timestamp->TimeStampHigh = dmatxdesc->DESC1;
1781
1782 /* Return function status */
1783 return HAL_OK;
1784 }
1785 else
1786 {
1787 /* Return function status */
1788 return HAL_ERROR;
1789 }
1790 }
1791
1792 /**
1793 * @brief Get receive timestamp.
1794 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1795 * the configuration information for ETHERNET module
1796 * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1797 * receive timestamp
1798 * @retval HAL status
1799 */
HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1800 HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1801 {
1802 if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1803 {
1804 /* Get timestamp low */
1805 timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow;
1806 /* Get timestamp high */
1807 timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh;
1808
1809 /* Return function status */
1810 return HAL_OK;
1811 }
1812 else
1813 {
1814 /* Return function status */
1815 return HAL_ERROR;
1816 }
1817 }
1818
1819 /**
1820 * @brief Register the Tx Ptp callback.
1821 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1822 * the configuration information for ETHERNET module
1823 * @param txPtpCallback: Function to handle Ptp transmission
1824 * @retval HAL status
1825 */
HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef * heth,pETH_txPtpCallbackTypeDef txPtpCallback)1826 HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
1827 {
1828 if (txPtpCallback == NULL)
1829 {
1830 /* No buffer to save */
1831 return HAL_ERROR;
1832 }
1833 /* Set Function to handle Tx Ptp */
1834 heth->txPtpCallback = txPtpCallback;
1835
1836 return HAL_OK;
1837 }
1838
1839 /**
1840 * @brief Unregister the Tx Ptp callback.
1841 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1842 * the configuration information for ETHERNET module
1843 * @retval HAL status
1844 */
HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef * heth)1845 HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
1846 {
1847 /* Set function to allocate buffer */
1848 heth->txPtpCallback = HAL_ETH_TxPtpCallback;
1849
1850 return HAL_OK;
1851 }
1852
1853 /**
1854 * @brief Tx Ptp callback.
1855 * @param buff: pointer to application buffer
1856 * @param timestamp: pointer to ETH_TimeStampTypeDef structure that contains
1857 * transmission timestamp
1858 * @retval None
1859 */
HAL_ETH_TxPtpCallback(uint32_t * buff,ETH_TimeStampTypeDef * timestamp)1860 __weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
1861 {
1862 /* Prevent unused argument(s) compilation warning */
1863 UNUSED(buff);
1864 /* NOTE : This function Should not be modified, when the callback is needed,
1865 the HAL_ETH_TxPtpCallback could be implemented in the user file
1866 */
1867 }
1868 #endif /* HAL_ETH_USE_PTP */
1869
1870 /**
1871 * @brief This function handles ETH interrupt request.
1872 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
1873 * the configuration information for ETHERNET module
1874 * @retval HAL status
1875 */
HAL_ETH_IRQHandler(ETH_HandleTypeDef * heth)1876 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1877 {
1878 uint32_t mac_flag = READ_REG(heth->Instance->MACISR);
1879 uint32_t dma_flag = READ_REG(heth->Instance->DMACSR);
1880 uint32_t dma_itsource = READ_REG(heth->Instance->DMACIER);
1881 uint32_t exti_d1_flag = READ_REG(EXTI_D1->PR3);
1882 #if defined(DUAL_CORE)
1883 uint32_t exti_d2_flag = READ_REG(EXTI_D2->PR3);
1884 #endif /* DUAL_CORE */
1885
1886 /* Packet received */
1887 if (((dma_flag & ETH_DMACSR_RI) != 0U) && ((dma_itsource & ETH_DMACIER_RIE) != 0U))
1888 {
1889 /* Clear the Eth DMA Rx IT pending bits */
1890 __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
1891
1892 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1893 /*Call registered Receive complete callback*/
1894 heth->RxCpltCallback(heth);
1895 #else
1896 /* Receive complete callback */
1897 HAL_ETH_RxCpltCallback(heth);
1898 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1899 }
1900
1901 /* Packet transmitted */
1902 if (((dma_flag & ETH_DMACSR_TI) != 0U) && ((dma_itsource & ETH_DMACIER_TIE) != 0U))
1903 {
1904 /* Clear the Eth DMA Tx IT pending bits */
1905 __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);
1906
1907 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1908 /*Call registered Transmit complete callback*/
1909 heth->TxCpltCallback(heth);
1910 #else
1911 /* Transfer complete callback */
1912 HAL_ETH_TxCpltCallback(heth);
1913 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1914 }
1915
1916 /* ETH DMA Error */
1917 if (((dma_flag & ETH_DMACSR_AIS) != 0U) && ((dma_itsource & ETH_DMACIER_AIE) != 0U))
1918 {
1919 heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1920 /* if fatal bus error occurred */
1921 if ((dma_flag & ETH_DMACSR_FBE) != 0U)
1922 {
1923 /* Get DMA error code */
1924 heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS));
1925
1926 /* Disable all interrupts */
1927 __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE);
1928
1929 /* Set HAL state to ERROR */
1930 heth->gState = HAL_ETH_STATE_ERROR;
1931 }
1932 else
1933 {
1934 /* Get DMA error status */
1935 heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1936 ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1937
1938 /* Clear the interrupt summary flag */
1939 __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1940 ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1941 }
1942 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1943 /* Call registered Error callback*/
1944 heth->ErrorCallback(heth);
1945 #else
1946 /* Ethernet DMA Error callback */
1947 HAL_ETH_ErrorCallback(heth);
1948 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1949 }
1950
1951 /* ETH MAC Error IT */
1952 if (((mac_flag & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \
1953 ((mac_flag & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE))
1954 {
1955 heth->ErrorCode |= HAL_ETH_ERROR_MAC;
1956
1957 /* Get MAC Rx Tx status and clear Status register pending bit */
1958 heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR);
1959
1960 heth->gState = HAL_ETH_STATE_ERROR;
1961
1962 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1963 /* Call registered Error callback*/
1964 heth->ErrorCallback(heth);
1965 #else
1966 /* Ethernet Error callback */
1967 HAL_ETH_ErrorCallback(heth);
1968 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1969 heth->MACErrorCode = (uint32_t)(0x0U);
1970 }
1971
1972 /* ETH PMT IT */
1973 if ((mac_flag & ETH_MAC_PMT_IT) != 0U)
1974 {
1975 /* Get MAC Wake-up source and clear the status register pending bit */
1976 heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD));
1977
1978 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1979 /* Call registered PMT callback*/
1980 heth->PMTCallback(heth);
1981 #else
1982 /* Ethernet PMT callback */
1983 HAL_ETH_PMTCallback(heth);
1984 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1985
1986 heth->MACWakeUpEvent = (uint32_t)(0x0U);
1987 }
1988
1989 /* ETH EEE IT */
1990 if ((mac_flag & ETH_MAC_LPI_IT) != 0U)
1991 {
1992 /* Get MAC LPI interrupt source and clear the status register pending bit */
1993 heth->MACLPIEvent = READ_BIT(heth->Instance->MACLCSR, 0x0000000FU);
1994
1995 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1996 /* Call registered EEE callback*/
1997 heth->EEECallback(heth);
1998 #else
1999 /* Ethernet EEE callback */
2000 HAL_ETH_EEECallback(heth);
2001 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2002
2003 heth->MACLPIEvent = (uint32_t)(0x0U);
2004 }
2005
2006 #if defined(DUAL_CORE)
2007 if (HAL_GetCurrentCPUID() == CM7_CPUID)
2008 {
2009 /* check ETH WAKEUP exti flag */
2010 if ((exti_d1_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
2011 {
2012 /* Clear ETH WAKEUP Exti pending bit */
2013 __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2014 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2015 /* Call registered WakeUp callback*/
2016 heth->WakeUpCallback(heth);
2017 #else
2018 /* ETH WAKEUP callback */
2019 HAL_ETH_WakeUpCallback(heth);
2020 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2021 }
2022 }
2023 else
2024 {
2025 /* check ETH WAKEUP exti flag */
2026 if ((exti_d2_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
2027 {
2028 /* Clear ETH WAKEUP Exti pending bit */
2029 __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2030 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2031 /* Call registered WakeUp callback*/
2032 heth->WakeUpCallback(heth);
2033 #else
2034 /* ETH WAKEUP callback */
2035 HAL_ETH_WakeUpCallback(heth);
2036 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2037 }
2038 }
2039 #else /* DUAL_CORE not defined */
2040 /* check ETH WAKEUP exti flag */
2041 if ((exti_d1_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
2042 {
2043 /* Clear ETH WAKEUP Exti pending bit */
2044 __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2045 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2046 /* Call registered WakeUp callback*/
2047 heth->WakeUpCallback(heth);
2048 #else
2049 /* ETH WAKEUP callback */
2050 HAL_ETH_WakeUpCallback(heth);
2051 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2052 }
2053 #endif /* DUAL_CORE */
2054 }
2055
2056 /**
2057 * @brief Tx Transfer completed callbacks.
2058 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2059 * the configuration information for ETHERNET module
2060 * @retval None
2061 */
HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth)2062 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
2063 {
2064 /* Prevent unused argument(s) compilation warning */
2065 UNUSED(heth);
2066 /* NOTE : This function Should not be modified, when the callback is needed,
2067 the HAL_ETH_TxCpltCallback could be implemented in the user file
2068 */
2069 }
2070
2071 /**
2072 * @brief Rx Transfer completed callbacks.
2073 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2074 * the configuration information for ETHERNET module
2075 * @retval None
2076 */
HAL_ETH_RxCpltCallback(ETH_HandleTypeDef * heth)2077 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
2078 {
2079 /* Prevent unused argument(s) compilation warning */
2080 UNUSED(heth);
2081 /* NOTE : This function Should not be modified, when the callback is needed,
2082 the HAL_ETH_RxCpltCallback could be implemented in the user file
2083 */
2084 }
2085
2086 /**
2087 * @brief Ethernet transfer error callbacks
2088 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2089 * the configuration information for ETHERNET module
2090 * @retval None
2091 */
HAL_ETH_ErrorCallback(ETH_HandleTypeDef * heth)2092 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
2093 {
2094 /* Prevent unused argument(s) compilation warning */
2095 UNUSED(heth);
2096 /* NOTE : This function Should not be modified, when the callback is needed,
2097 the HAL_ETH_ErrorCallback could be implemented in the user file
2098 */
2099 }
2100
2101 /**
2102 * @brief Ethernet Power Management module IT callback
2103 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2104 * the configuration information for ETHERNET module
2105 * @retval None
2106 */
HAL_ETH_PMTCallback(ETH_HandleTypeDef * heth)2107 __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
2108 {
2109 /* Prevent unused argument(s) compilation warning */
2110 UNUSED(heth);
2111 /* NOTE : This function Should not be modified, when the callback is needed,
2112 the HAL_ETH_PMTCallback could be implemented in the user file
2113 */
2114 }
2115
2116 /**
2117 * @brief Energy Efficient Etherent IT callback
2118 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2119 * the configuration information for ETHERNET module
2120 * @retval None
2121 */
HAL_ETH_EEECallback(ETH_HandleTypeDef * heth)2122 __weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth)
2123 {
2124 /* Prevent unused argument(s) compilation warning */
2125 UNUSED(heth);
2126 /* NOTE : This function Should not be modified, when the callback is needed,
2127 the HAL_ETH_EEECallback could be implemented in the user file
2128 */
2129 }
2130
2131 /**
2132 * @brief ETH WAKEUP interrupt callback
2133 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2134 * the configuration information for ETHERNET module
2135 * @retval None
2136 */
HAL_ETH_WakeUpCallback(ETH_HandleTypeDef * heth)2137 __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
2138 {
2139 /* Prevent unused argument(s) compilation warning */
2140 UNUSED(heth);
2141 /* NOTE : This function Should not be modified, when the callback is needed,
2142 the HAL_ETH_WakeUpCallback could be implemented in the user file
2143 */
2144 }
2145
2146 /**
2147 * @brief Read a PHY register
2148 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2149 * the configuration information for ETHERNET module
2150 * @param PHYAddr: PHY port address, must be a value from 0 to 31
2151 * @param PHYReg: PHY register address, must be a value from 0 to 31
2152 * @param pRegValue: parameter to hold read value
2153 * @retval HAL status
2154 */
HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t * pRegValue)2155 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2156 uint32_t *pRegValue)
2157 {
2158 uint32_t tickstart;
2159 uint32_t tmpreg;
2160
2161 /* Check for the Busy flag */
2162 if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2163 {
2164 return HAL_ERROR;
2165 }
2166
2167 /* Get the MACMDIOAR value */
2168 WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2169
2170 /* Prepare the MDIO Address Register value
2171 - Set the PHY device address
2172 - Set the PHY register address
2173 - Set the read mode
2174 - Set the MII Busy bit */
2175
2176 MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2177 MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2178 MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD);
2179 SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2180
2181 /* Write the result value into the MDII Address register */
2182 WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);
2183
2184 tickstart = HAL_GetTick();
2185
2186 /* Wait for the Busy flag */
2187 while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2188 {
2189 if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2190 {
2191 return HAL_ERROR;
2192 }
2193 }
2194
2195 /* Get MACMIIDR value */
2196 WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR);
2197
2198 return HAL_OK;
2199 }
2200
2201 /**
2202 * @brief Writes to a PHY register.
2203 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2204 * the configuration information for ETHERNET module
2205 * @param PHYAddr: PHY port address, must be a value from 0 to 31
2206 * @param PHYReg: PHY register address, must be a value from 0 to 31
2207 * @param RegValue: the value to write
2208 * @retval HAL status
2209 */
HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t RegValue)2210 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2211 uint32_t RegValue)
2212 {
2213 uint32_t tickstart;
2214 uint32_t tmpreg;
2215
2216 /* Check for the Busy flag */
2217 if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2218 {
2219 return HAL_ERROR;
2220 }
2221
2222 /* Get the MACMDIOAR value */
2223 WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2224
2225 /* Prepare the MDIO Address Register value
2226 - Set the PHY device address
2227 - Set the PHY register address
2228 - Set the write mode
2229 - Set the MII Busy bit */
2230
2231 MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2232 MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2233 MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR);
2234 SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2235
2236 /* Give the value to the MII data register */
2237 WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue);
2238
2239 /* Write the result value into the MII Address register */
2240 WRITE_REG(ETH->MACMDIOAR, tmpreg);
2241
2242 tickstart = HAL_GetTick();
2243
2244 /* Wait for the Busy flag */
2245 while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2246 {
2247 if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2248 {
2249 return HAL_ERROR;
2250 }
2251 }
2252
2253 return HAL_OK;
2254 }
2255
2256 /**
2257 * @}
2258 */
2259
2260 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
2261 * @brief ETH control functions
2262 *
2263 @verbatim
2264 ==============================================================================
2265 ##### Peripheral Control functions #####
2266 ==============================================================================
2267 [..]
2268 This subsection provides a set of functions allowing to control the ETH
2269 peripheral.
2270
2271 @endverbatim
2272 * @{
2273 */
2274 /**
2275 * @brief Get the configuration of the MAC and MTL subsystems.
2276 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2277 * the configuration information for ETHERNET module
2278 * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
2279 * the configuration of the MAC.
2280 * @retval HAL Status
2281 */
HAL_ETH_GetMACConfig(const ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2282 HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2283 {
2284 if (macconf == NULL)
2285 {
2286 return HAL_ERROR;
2287 }
2288
2289 /* Get MAC parameters */
2290 macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN);
2291 macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
2292 macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
2293 macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE;
2294 macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U)
2295 ? ENABLE : DISABLE;
2296 macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE;
2297 macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR,
2298 ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE;
2299 macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
2300 macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
2301 macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
2302 macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE;
2303 macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE;
2304 macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE;
2305 macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE;
2306 macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE;
2307 macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE;
2308 macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR,
2309 ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE;
2310 macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG);
2311 macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE;
2312 macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC);
2313
2314 macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL);
2315 macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE;
2316 macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE;
2317 macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR,
2318 ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE;
2319 macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U)
2320 ? ENABLE : DISABLE;
2321 macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25;
2322
2323 macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE;
2324 macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO);
2325
2326 macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE;
2327 macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE;
2328 macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT);
2329 macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16);
2330 macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE;
2331 macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U)
2332 ? ENABLE : DISABLE;
2333
2334 macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF));
2335
2336 macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF));
2337 macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2338 ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE;
2339 macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE;
2340 macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2341 ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE;
2342
2343 return HAL_OK;
2344 }
2345
2346 /**
2347 * @brief Get the configuration of the DMA.
2348 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2349 * the configuration information for ETHERNET module
2350 * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2351 * the configuration of the ETH DMA.
2352 * @retval HAL Status
2353 */
HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2354 HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2355 {
2356 if (dmaconf == NULL)
2357 {
2358 return HAL_ERROR;
2359 }
2360
2361 dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE;
2362 dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB);
2363 dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB) >> 15) > 0U) ? ENABLE : DISABLE;
2364
2365 dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA));
2366
2367 dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL) >> 16) > 0U) ? ENABLE : DISABLE;
2368 dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS);
2369
2370 dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE;
2371 dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL);
2372
2373 dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE;
2374 dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE;
2375 dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL);
2376
2377 return HAL_OK;
2378 }
2379
2380 /**
2381 * @brief Set the MAC configuration.
2382 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2383 * the configuration information for ETHERNET module
2384 * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains
2385 * the configuration of the MAC.
2386 * @retval HAL status
2387 */
HAL_ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2388 HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2389 {
2390 if (macconf == NULL)
2391 {
2392 return HAL_ERROR;
2393 }
2394
2395 if (heth->gState == HAL_ETH_STATE_READY)
2396 {
2397 ETH_SetMACConfig(heth, macconf);
2398
2399 return HAL_OK;
2400 }
2401 else
2402 {
2403 return HAL_ERROR;
2404 }
2405 }
2406
2407 /**
2408 * @brief Set the ETH DMA configuration.
2409 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2410 * the configuration information for ETHERNET module
2411 * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2412 * the configuration of the ETH DMA.
2413 * @retval HAL status
2414 */
HAL_ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2415 HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2416 {
2417 if (dmaconf == NULL)
2418 {
2419 return HAL_ERROR;
2420 }
2421
2422 if (heth->gState == HAL_ETH_STATE_READY)
2423 {
2424 ETH_SetDMAConfig(heth, dmaconf);
2425
2426 return HAL_OK;
2427 }
2428 else
2429 {
2430 return HAL_ERROR;
2431 }
2432 }
2433
2434 /**
2435 * @brief Configures the Clock range of ETH MDIO interface.
2436 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2437 * the configuration information for ETHERNET module
2438 * @retval None
2439 */
HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef * heth)2440 void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2441 {
2442 uint32_t hclk;
2443 uint32_t tmpreg;
2444
2445 /* Get the ETHERNET MACMDIOAR value */
2446 tmpreg = (heth->Instance)->MACMDIOAR;
2447
2448 /* Clear CSR Clock Range bits */
2449 tmpreg &= ~ETH_MACMDIOAR_CR;
2450
2451 /* Get hclk frequency value */
2452 hclk = HAL_RCC_GetHCLKFreq();
2453
2454 /* Set CR bits depending on hclk value */
2455 if (hclk < 35000000U)
2456 {
2457 /* CSR Clock Range between 0-35 MHz */
2458 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16;
2459 }
2460 else if (hclk < 60000000U)
2461 {
2462 /* CSR Clock Range between 35-60 MHz */
2463 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26;
2464 }
2465 else if (hclk < 100000000U)
2466 {
2467 /* CSR Clock Range between 60-100 MHz */
2468 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42;
2469 }
2470 else if (hclk < 150000000U)
2471 {
2472 /* CSR Clock Range between 100-150 MHz */
2473 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62;
2474 }
2475 else if (hclk < 250000000U)
2476 {
2477 /* CSR Clock Range between 150-250 MHz */
2478 tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102;
2479 }
2480 else /* (hclk >= 250000000U) */
2481 {
2482 /* CSR Clock >= 250 MHz */
2483 tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV124);
2484 }
2485
2486 /* Configure the CSR Clock Range */
2487 (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg;
2488 }
2489
2490 /**
2491 * @brief Set the ETH MAC (L2) Filters configuration.
2492 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2493 * the configuration information for ETHERNET module
2494 * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2495 * the configuration of the ETH MAC filters.
2496 * @retval HAL status
2497 */
HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef * heth,const ETH_MACFilterConfigTypeDef * pFilterConfig)2498 HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig)
2499 {
2500 uint32_t filterconfig;
2501
2502 if (pFilterConfig == NULL)
2503 {
2504 return HAL_ERROR;
2505 }
2506
2507 filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2508 ((uint32_t)pFilterConfig->HashUnicast << 1) |
2509 ((uint32_t)pFilterConfig->HashMulticast << 2) |
2510 ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2511 ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2512 ((uint32_t)((pFilterConfig->BroadcastFilter == ENABLE) ? 1U : 0U) << 5) |
2513 ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2514 ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2515 ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2516 ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2517 pFilterConfig->ControlPacketsFilter);
2518
2519 MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig);
2520
2521 return HAL_OK;
2522 }
2523
2524 /**
2525 * @brief Get the ETH MAC (L2) Filters configuration.
2526 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2527 * the configuration information for ETHERNET module
2528 * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2529 * the configuration of the ETH MAC filters.
2530 * @retval HAL status
2531 */
HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2532 HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2533 {
2534 if (pFilterConfig == NULL)
2535 {
2536 return HAL_ERROR;
2537 }
2538
2539 pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE;
2540 pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE;
2541 pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE;
2542 pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2543 ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2544 pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE;
2545 pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) > 0U) ? ENABLE : DISABLE;
2546 pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF);
2547 pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2548 ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2549 pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2550 pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U)
2551 ? ENABLE : DISABLE;
2552 pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2553
2554 return HAL_OK;
2555 }
2556
2557 /**
2558 * @brief Set the source MAC Address to be matched.
2559 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2560 * the configuration information for ETHERNET module
2561 * @param AddrNbr: The MAC address to configure
2562 * This parameter must be a value of the following:
2563 * ETH_MAC_ADDRESS1
2564 * ETH_MAC_ADDRESS2
2565 * ETH_MAC_ADDRESS3
2566 * @param pMACAddr: Pointer to MAC address buffer data (6 bytes)
2567 * @retval HAL status
2568 */
HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef * heth,uint32_t AddrNbr,const uint8_t * pMACAddr)2569 HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr,
2570 const uint8_t *pMACAddr)
2571 {
2572 uint32_t macaddrlr;
2573 uint32_t macaddrhr;
2574
2575 if (pMACAddr == NULL)
2576 {
2577 return HAL_ERROR;
2578 }
2579
2580 /* Get mac addr high reg offset */
2581 macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
2582 /* Get mac addr low reg offset */
2583 macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
2584
2585 /* Set MAC addr bits 32 to 47 */
2586 (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2587 /* Set MAC addr bits 0 to 31 */
2588 (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2589 ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2590
2591 /* Enable address and set source address bit */
2592 (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE);
2593
2594 return HAL_OK;
2595 }
2596
2597 /**
2598 * @brief Set the ETH Hash Table Value.
2599 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2600 * the configuration information for ETHERNET module
2601 * @param pHashTable: pointer to a table of two 32 bit values, that contains
2602 * the 64 bits of the hash table.
2603 * @retval HAL status
2604 */
HAL_ETH_SetHashTable(ETH_HandleTypeDef * heth,uint32_t * pHashTable)2605 HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2606 {
2607 if (pHashTable == NULL)
2608 {
2609 return HAL_ERROR;
2610 }
2611
2612 heth->Instance->MACHT0R = pHashTable[0];
2613 heth->Instance->MACHT1R = pHashTable[1];
2614
2615 return HAL_OK;
2616 }
2617
2618 /**
2619 * @brief Set the VLAN Identifier for Rx packets
2620 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2621 * the configuration information for ETHERNET module
2622 * @param ComparisonBits: 12 or 16 bit comparison mode
2623 must be a value of @ref ETH_VLAN_Tag_Comparison
2624 * @param VLANIdentifier: VLAN Identifier value
2625 * @retval None
2626 */
HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t ComparisonBits,uint32_t VLANIdentifier)2627 void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2628 {
2629 if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2630 {
2631 MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier);
2632 CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2633 }
2634 else
2635 {
2636 MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier);
2637 SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2638 }
2639 }
2640
2641 /**
2642 * @brief Enters the Power down mode.
2643 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2644 * the configuration information for ETHERNET module
2645 * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2646 * that contains the Power Down configuration
2647 * @retval None.
2648 */
HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef * heth,const ETH_PowerDownConfigTypeDef * pPowerDownConfig)2649 void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2650 {
2651 uint32_t powerdownconfig;
2652
2653 powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) |
2654 ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) |
2655 ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) |
2656 ((uint32_t)pPowerDownConfig->WakeUpForward << 10) |
2657 ETH_MACPCSR_PWRDWN);
2658
2659 /* Enable PMT interrupt */
2660 __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE);
2661
2662 MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig);
2663 }
2664
2665 /**
2666 * @brief Exits from the Power down mode.
2667 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2668 * the configuration information for ETHERNET module
2669 * @retval None.
2670 */
HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef * heth)2671 void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2672 {
2673 /* clear wake up sources */
2674 CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST |
2675 ETH_MACPCSR_RWKPFE);
2676
2677 if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET)
2678 {
2679 /* Exit power down mode */
2680 CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN);
2681 }
2682
2683 /* Disable PMT interrupt */
2684 __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE);
2685 }
2686
2687 /**
2688 * @brief Set the WakeUp filter.
2689 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2690 * the configuration information for ETHERNET module
2691 * @param pFilter: pointer to filter registers values
2692 * @param Count: number of filter registers, must be from 1 to 8.
2693 * @retval None.
2694 */
HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef * heth,uint32_t * pFilter,uint32_t Count)2695 HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2696 {
2697 uint32_t regindex;
2698
2699 if (pFilter == NULL)
2700 {
2701 return HAL_ERROR;
2702 }
2703
2704 /* Reset Filter Pointer */
2705 SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST);
2706
2707 /* Wake up packet filter config */
2708 for (regindex = 0; regindex < Count; regindex++)
2709 {
2710 /* Write filter regs */
2711 WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]);
2712 }
2713
2714 return HAL_OK;
2715 }
2716
2717 /**
2718 * @}
2719 */
2720
2721 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2722 * @brief ETH State and Errors functions
2723 *
2724 @verbatim
2725 ==============================================================================
2726 ##### Peripheral State and Errors functions #####
2727 ==============================================================================
2728 [..]
2729 This subsection provides a set of functions allowing to return the State of
2730 ETH communication process, return Peripheral Errors occurred during communication
2731 process
2732
2733
2734 @endverbatim
2735 * @{
2736 */
2737
2738 /**
2739 * @brief Returns the ETH state.
2740 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2741 * the configuration information for ETHERNET module
2742 * @retval HAL state
2743 */
HAL_ETH_GetState(const ETH_HandleTypeDef * heth)2744 HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth)
2745 {
2746 return heth->gState;
2747 }
2748
2749 /**
2750 * @brief Returns the ETH error code
2751 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2752 * the configuration information for ETHERNET module
2753 * @retval ETH Error Code
2754 */
HAL_ETH_GetError(const ETH_HandleTypeDef * heth)2755 uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth)
2756 {
2757 return heth->ErrorCode;
2758 }
2759
2760 /**
2761 * @brief Returns the ETH DMA error code
2762 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2763 * the configuration information for ETHERNET module
2764 * @retval ETH DMA Error Code
2765 */
HAL_ETH_GetDMAError(const ETH_HandleTypeDef * heth)2766 uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth)
2767 {
2768 return heth->DMAErrorCode;
2769 }
2770
2771 /**
2772 * @brief Returns the ETH MAC error code
2773 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2774 * the configuration information for ETHERNET module
2775 * @retval ETH MAC Error Code
2776 */
HAL_ETH_GetMACError(const ETH_HandleTypeDef * heth)2777 uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth)
2778 {
2779 return heth->MACErrorCode;
2780 }
2781
2782 /**
2783 * @brief Returns the ETH MAC WakeUp event source
2784 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2785 * the configuration information for ETHERNET module
2786 * @retval ETH MAC WakeUp event source
2787 */
HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef * heth)2788 uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth)
2789 {
2790 return heth->MACWakeUpEvent;
2791 }
2792
2793 /**
2794 * @brief Returns the ETH Tx Buffers in use number
2795 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2796 * the configuration information for ETHERNET module
2797 * @retval ETH Tx Buffers in use number
2798 */
HAL_ETH_GetTxBuffersNumber(const ETH_HandleTypeDef * heth)2799 uint32_t HAL_ETH_GetTxBuffersNumber(const ETH_HandleTypeDef *heth)
2800 {
2801 return heth->TxDescList.BuffersInUse;
2802 }
2803 /**
2804 * @}
2805 */
2806
2807 /**
2808 * @}
2809 */
2810
2811 /** @addtogroup ETH_Private_Functions ETH Private Functions
2812 * @{
2813 */
2814
ETH_SetMACConfig(ETH_HandleTypeDef * heth,const ETH_MACConfigTypeDef * macconf)2815 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf)
2816 {
2817 uint32_t macregval;
2818
2819 /*------------------------ MACCR Configuration --------------------*/
2820 macregval = (macconf->InterPacketGapVal |
2821 macconf->SourceAddrControl |
2822 ((uint32_t)macconf->ChecksumOffload << 27) |
2823 ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) |
2824 ((uint32_t)macconf->Support2KPacket << 22) |
2825 ((uint32_t)macconf->CRCStripTypePacket << 21) |
2826 ((uint32_t)macconf->AutomaticPadCRCStrip << 20) |
2827 ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) |
2828 ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) |
2829 ((uint32_t)macconf->JumboPacket << 16) |
2830 macconf->Speed |
2831 macconf->DuplexMode |
2832 ((uint32_t)macconf->LoopbackMode << 12) |
2833 ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) |
2834 ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) |
2835 ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) |
2836 ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) |
2837 macconf->BackOffLimit |
2838 ((uint32_t)macconf->DeferralCheck << 4) |
2839 macconf->PreambleLength);
2840
2841 /* Write to MACCR */
2842 MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval);
2843
2844 /*------------------------ MACECR Configuration --------------------*/
2845 macregval = ((macconf->ExtendedInterPacketGapVal << 25) |
2846 ((uint32_t)macconf->ExtendedInterPacketGap << 24) |
2847 ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) |
2848 ((uint32_t)macconf->SlowProtocolDetect << 17) |
2849 ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) |
2850 macconf->GiantPacketSizeLimit);
2851
2852 /* Write to MACECR */
2853 MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval);
2854
2855 /*------------------------ MACWTR Configuration --------------------*/
2856 macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) |
2857 macconf->WatchdogTimeout);
2858
2859 /* Write to MACWTR */
2860 MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval);
2861
2862 /*------------------------ MACTFCR Configuration --------------------*/
2863 macregval = (((uint32_t)macconf->TransmitFlowControl << 1) |
2864 macconf->PauseLowThreshold |
2865 ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) |
2866 (macconf->PauseTime << 16));
2867
2868 /* Write to MACTFCR */
2869 MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval);
2870
2871 /*------------------------ MACRFCR Configuration --------------------*/
2872 macregval = ((uint32_t)macconf->ReceiveFlowControl |
2873 ((uint32_t)macconf->UnicastPausePacketDetect << 1));
2874
2875 /* Write to MACRFCR */
2876 MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval);
2877
2878 /*------------------------ MTLTQOMR Configuration --------------------*/
2879 /* Write to MTLTQOMR */
2880 MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode);
2881
2882 /*------------------------ MTLRQOMR Configuration --------------------*/
2883 macregval = (macconf->ReceiveQueueMode |
2884 ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) |
2885 ((uint32_t)macconf->ForwardRxErrorPacket << 4) |
2886 ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3));
2887
2888 /* Write to MTLRQOMR */
2889 MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval);
2890 }
2891
ETH_SetDMAConfig(ETH_HandleTypeDef * heth,const ETH_DMAConfigTypeDef * dmaconf)2892 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf)
2893 {
2894 uint32_t dmaregval;
2895
2896 /*------------------------ DMAMR Configuration --------------------*/
2897 MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration);
2898
2899 /*------------------------ DMASBMR Configuration --------------------*/
2900 dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) |
2901 dmaconf->BurstMode |
2902 ((uint32_t)dmaconf->RebuildINCRxBurst << 15));
2903
2904 MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval);
2905
2906 /*------------------------ DMACCR Configuration --------------------*/
2907 dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) |
2908 dmaconf->MaximumSegmentSize);
2909 MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval);
2910
2911 /*------------------------ DMACTCR Configuration --------------------*/
2912 dmaregval = (dmaconf->TxDMABurstLength |
2913 ((uint32_t)dmaconf->SecondPacketOperate << 4) |
2914 ((uint32_t)dmaconf->TCPSegmentation << 12));
2915
2916 MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval);
2917
2918 /*------------------------ DMACRCR Configuration --------------------*/
2919 dmaregval = (((uint32_t)dmaconf->FlushRxPacket << 31) |
2920 dmaconf->RxDMABurstLength);
2921
2922 /* Write to DMACRCR */
2923 MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval);
2924 }
2925
2926 /**
2927 * @brief Configures Ethernet MAC and DMA with default parameters.
2928 * called by HAL_ETH_Init() API.
2929 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
2930 * the configuration information for ETHERNET module
2931 * @retval HAL status
2932 */
ETH_MACDMAConfig(ETH_HandleTypeDef * heth)2933 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
2934 {
2935 ETH_MACConfigTypeDef macDefaultConf;
2936 ETH_DMAConfigTypeDef dmaDefaultConf;
2937
2938 /*--------------- ETHERNET MAC registers default Configuration --------------*/
2939 macDefaultConf.AutomaticPadCRCStrip = ENABLE;
2940 macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2941 macDefaultConf.CarrierSenseBeforeTransmit = DISABLE;
2942 macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2943 macDefaultConf.ChecksumOffload = ENABLE;
2944 macDefaultConf.CRCCheckingRxPackets = ENABLE;
2945 macDefaultConf.CRCStripTypePacket = ENABLE;
2946 macDefaultConf.DeferralCheck = DISABLE;
2947 macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE;
2948 macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2949 macDefaultConf.ExtendedInterPacketGap = DISABLE;
2950 macDefaultConf.ExtendedInterPacketGapVal = 0x0U;
2951 macDefaultConf.ForwardRxErrorPacket = DISABLE;
2952 macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE;
2953 macDefaultConf.GiantPacketSizeLimit = 0x618U;
2954 macDefaultConf.GiantPacketSizeLimitControl = DISABLE;
2955 macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT;
2956 macDefaultConf.Jabber = ENABLE;
2957 macDefaultConf.JumboPacket = DISABLE;
2958 macDefaultConf.LoopbackMode = DISABLE;
2959 macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4;
2960 macDefaultConf.PauseTime = 0x0U;
2961 macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7;
2962 macDefaultConf.ProgrammableWatchdog = DISABLE;
2963 macDefaultConf.ReceiveFlowControl = DISABLE;
2964 macDefaultConf.ReceiveOwn = ENABLE;
2965 macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD;
2966 macDefaultConf.RetryTransmission = ENABLE;
2967 macDefaultConf.SlowProtocolDetect = DISABLE;
2968 macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0;
2969 macDefaultConf.Speed = ETH_SPEED_100M;
2970 macDefaultConf.Support2KPacket = DISABLE;
2971 macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD;
2972 macDefaultConf.TransmitFlowControl = DISABLE;
2973 macDefaultConf.UnicastPausePacketDetect = DISABLE;
2974 macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE;
2975 macDefaultConf.Watchdog = ENABLE;
2976 macDefaultConf.WatchdogTimeout = ETH_MACWTR_WTO_2KB;
2977 macDefaultConf.ZeroQuantaPause = ENABLE;
2978
2979 /* MAC default configuration */
2980 ETH_SetMACConfig(heth, &macDefaultConf);
2981
2982 /*--------------- ETHERNET DMA registers default Configuration --------------*/
2983 dmaDefaultConf.AddressAlignedBeats = ENABLE;
2984 dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2985 dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1;
2986 dmaDefaultConf.FlushRxPacket = DISABLE;
2987 dmaDefaultConf.PBLx8Mode = DISABLE;
2988 dmaDefaultConf.RebuildINCRxBurst = DISABLE;
2989 dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2990 dmaDefaultConf.SecondPacketOperate = DISABLE;
2991 dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2992 dmaDefaultConf.TCPSegmentation = DISABLE;
2993 dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT;
2994
2995 /* DMA default configuration */
2996 ETH_SetDMAConfig(heth, &dmaDefaultConf);
2997 }
2998
2999 /**
3000 * @brief Initializes the DMA Tx descriptors.
3001 * called by HAL_ETH_Init() API.
3002 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
3003 * the configuration information for ETHERNET module
3004 * @retval None
3005 */
ETH_DMATxDescListInit(ETH_HandleTypeDef * heth)3006 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
3007 {
3008 ETH_DMADescTypeDef *dmatxdesc;
3009 uint32_t i;
3010
3011 /* Fill each DMATxDesc descriptor with the right values */
3012 for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
3013 {
3014 dmatxdesc = heth->Init.TxDesc + i;
3015
3016 WRITE_REG(dmatxdesc->DESC0, 0x0U);
3017 WRITE_REG(dmatxdesc->DESC1, 0x0U);
3018 WRITE_REG(dmatxdesc->DESC2, 0x0U);
3019 WRITE_REG(dmatxdesc->DESC3, 0x0U);
3020
3021 WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
3022
3023 }
3024
3025 heth->TxDescList.CurTxDesc = 0;
3026
3027 /* Set Transmit Descriptor Ring Length */
3028 WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT - 1U));
3029
3030 /* Set Transmit Descriptor List Address */
3031 WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc);
3032
3033 /* Set Transmit Descriptor Tail pointer */
3034 WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc);
3035 }
3036
3037 /**
3038 * @brief Initializes the DMA Rx descriptors in chain mode.
3039 * called by HAL_ETH_Init() API.
3040 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
3041 * the configuration information for ETHERNET module
3042 * @retval None
3043 */
ETH_DMARxDescListInit(ETH_HandleTypeDef * heth)3044 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
3045 {
3046 ETH_DMADescTypeDef *dmarxdesc;
3047 uint32_t i;
3048
3049 for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
3050 {
3051 dmarxdesc = heth->Init.RxDesc + i;
3052
3053 WRITE_REG(dmarxdesc->DESC0, 0x0U);
3054 WRITE_REG(dmarxdesc->DESC1, 0x0U);
3055 WRITE_REG(dmarxdesc->DESC2, 0x0U);
3056 WRITE_REG(dmarxdesc->DESC3, 0x0U);
3057 WRITE_REG(dmarxdesc->BackupAddr0, 0x0U);
3058 WRITE_REG(dmarxdesc->BackupAddr1, 0x0U);
3059
3060 /* Set Rx descritors addresses */
3061 WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
3062
3063 }
3064
3065 WRITE_REG(heth->RxDescList.RxDescIdx, 0U);
3066 WRITE_REG(heth->RxDescList.RxDescCnt, 0U);
3067 WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U);
3068 WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U);
3069 WRITE_REG(heth->RxDescList.ItMode, 0U);
3070
3071 /* Set Receive Descriptor Ring Length */
3072 WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U)));
3073
3074 /* Set Receive Descriptor List Address */
3075 WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc);
3076
3077 /* Set Receive Descriptor Tail pointer Address */
3078 WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U))));
3079 }
3080
3081 /**
3082 * @brief Prepare Tx DMA descriptor before transmission.
3083 * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
3084 * @param heth: pointer to a ETH_HandleTypeDef structure that contains
3085 * the configuration information for ETHERNET module
3086 * @param pTxConfig: Tx packet configuration
3087 * @param ItMode: Enable or disable Tx EOT interrupt
3088 * @retval Status
3089 */
ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef * heth,const ETH_TxPacketConfigTypeDef * pTxConfig,uint32_t ItMode)3090 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
3091 uint32_t ItMode)
3092 {
3093 ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
3094 uint32_t descidx = dmatxdesclist->CurTxDesc;
3095 uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
3096 uint32_t idx;
3097 uint32_t descnbr = 0;
3098 ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3099
3100 ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer;
3101 uint32_t bd_count = 0;
3102 uint32_t primask_bit;
3103
3104 /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
3105 if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3106 || (dmatxdesclist->PacketAddress[descidx] != NULL))
3107 {
3108 return HAL_ETH_ERROR_BUSY;
3109 }
3110
3111 /***************************************************************************/
3112 /***************** Context descriptor configuration (Optional) **********/
3113 /***************************************************************************/
3114 /* If VLAN tag is enabled for this packet */
3115 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3116 {
3117 /* Set vlan tag value */
3118 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag);
3119 /* Set vlan tag valid bit */
3120 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV);
3121 /* Set the descriptor as the vlan input source */
3122 SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI);
3123
3124 /* if inner VLAN is enabled */
3125 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET)
3126 {
3127 /* Set inner vlan tag value */
3128 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16));
3129 /* Set inner vlan tag valid bit */
3130 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV);
3131
3132 /* Set Vlan Tag control */
3133 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl);
3134
3135 /* Set the descriptor as the inner vlan input source */
3136 SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI);
3137 /* Enable double VLAN processing */
3138 SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP);
3139 }
3140 }
3141
3142 /* if tcp segmentation is enabled for this packet */
3143 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3144 {
3145 /* Set MSS value */
3146 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize);
3147 /* Set MSS valid bit */
3148 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV);
3149 }
3150
3151 if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3152 || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET))
3153 {
3154 /* Set as context descriptor */
3155 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT);
3156 /* Ensure rest of descriptor is written to RAM before the OWN bit */
3157 __DMB();
3158 /* Set own bit */
3159 SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3160 /* Increment current tx descriptor index */
3161 INCR_TX_DESC_INDEX(descidx, 1U);
3162 /* Get current descriptor address */
3163 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3164
3165 descnbr += 1U;
3166
3167 /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
3168 if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3169 {
3170 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
3171 /* Ensure rest of descriptor is written to RAM before the OWN bit */
3172 __DMB();
3173 /* Clear own bit */
3174 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3175
3176 return HAL_ETH_ERROR_BUSY;
3177 }
3178 }
3179
3180 /***************************************************************************/
3181 /***************** Normal descriptors configuration *****************/
3182 /***************************************************************************/
3183
3184 descnbr += 1U;
3185
3186 /* Set header or buffer 1 address */
3187 WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3188 /* Set header or buffer 1 Length */
3189 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3190
3191 if (txbuffer->next != NULL)
3192 {
3193 txbuffer = txbuffer->next;
3194 /* Set buffer 2 address */
3195 WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3196 /* Set buffer 2 Length */
3197 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3198 }
3199 else
3200 {
3201 WRITE_REG(dmatxdesc->DESC1, 0x0U);
3202 /* Set buffer 2 Length */
3203 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3204 }
3205
3206 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3207 {
3208 /* Set TCP Header length */
3209 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19));
3210 /* Set TCP payload length */
3211 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3212 /* Set TCP Segmentation Enabled bit */
3213 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3214 }
3215 else
3216 {
3217 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3218
3219 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3220 {
3221 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3222 }
3223
3224 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET)
3225 {
3226 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl);
3227 }
3228 }
3229
3230 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3231 {
3232 /* Set Vlan Tag control */
3233 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl);
3234 }
3235
3236 /* Mark it as First Descriptor */
3237 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3238 /* Mark it as NORMAL descriptor */
3239 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3240 /* Ensure rest of descriptor is written to RAM before the OWN bit */
3241 __DMB();
3242 /* set OWN bit of FIRST descriptor */
3243 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3244
3245 /* If source address insertion/replacement is enabled for this packet */
3246 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET)
3247 {
3248 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl);
3249 }
3250
3251 /* only if the packet is split into more than one descriptors > 1 */
3252 while (txbuffer->next != NULL)
3253 {
3254 /* Clear the LD bit of previous descriptor */
3255 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3256 /* Increment current tx descriptor index */
3257 INCR_TX_DESC_INDEX(descidx, 1U);
3258 /* Get current descriptor address */
3259 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3260
3261 /* Clear the FD bit of new Descriptor */
3262 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3263
3264 /* Current Tx Descriptor Owned by DMA: cannot be used by the application */
3265 if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN)
3266 || (dmatxdesclist->PacketAddress[descidx] != NULL))
3267 {
3268 descidx = firstdescidx;
3269 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3270
3271 /* clear previous desc own bit */
3272 for (idx = 0; idx < descnbr; idx ++)
3273 {
3274 /* Ensure rest of descriptor is written to RAM before the OWN bit */
3275 __DMB();
3276
3277 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3278
3279 /* Increment current tx descriptor index */
3280 INCR_TX_DESC_INDEX(descidx, 1U);
3281 /* Get current descriptor address */
3282 dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3283 }
3284
3285 return HAL_ETH_ERROR_BUSY;
3286 }
3287
3288 descnbr += 1U;
3289
3290 /* Get the next Tx buffer in the list */
3291 txbuffer = txbuffer->next;
3292
3293 /* Set header or buffer 1 address */
3294 WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3295 /* Set header or buffer 1 Length */
3296 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3297
3298 if (txbuffer->next != NULL)
3299 {
3300 /* Get the next Tx buffer in the list */
3301 txbuffer = txbuffer->next;
3302 /* Set buffer 2 address */
3303 WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3304 /* Set buffer 2 Length */
3305 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3306 }
3307 else
3308 {
3309 WRITE_REG(dmatxdesc->DESC1, 0x0U);
3310 /* Set buffer 2 Length */
3311 MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3312 }
3313
3314 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3315 {
3316 /* Set TCP payload length */
3317 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3318 /* Set TCP Segmentation Enabled bit */
3319 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3320 }
3321 else
3322 {
3323 /* Set the packet length */
3324 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3325
3326 if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3327 {
3328 /* Checksum Insertion Control */
3329 MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3330 }
3331 }
3332
3333 bd_count += 1U;
3334
3335 /* Ensure rest of descriptor is written to RAM before the OWN bit */
3336 __DMB();
3337 /* Set Own bit */
3338 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3339 /* Mark it as NORMAL descriptor */
3340 CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3341 }
3342
3343 if (ItMode != ((uint32_t)RESET))
3344 {
3345 /* Set Interrupt on completion bit */
3346 SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3347 }
3348 else
3349 {
3350 /* Clear Interrupt on completion bit */
3351 CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3352 }
3353
3354 /* Mark it as LAST descriptor */
3355 SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3356 /* Save the current packet address to expose it to the application */
3357 dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
3358
3359 dmatxdesclist->CurTxDesc = descidx;
3360
3361 /* Enter critical section */
3362 primask_bit = __get_PRIMASK();
3363 __set_PRIMASK(1);
3364
3365 dmatxdesclist->BuffersInUse += bd_count + 1U;
3366
3367 /* Exit critical section: restore previous priority mask */
3368 __set_PRIMASK(primask_bit);
3369
3370 /* Return function status */
3371 return HAL_ETH_ERROR_NONE;
3372 }
3373
3374 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
ETH_InitCallbacksToDefault(ETH_HandleTypeDef * heth)3375 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
3376 {
3377 /* Init the ETH Callback settings */
3378 heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */
3379 heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */
3380 heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */
3381 heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */
3382 heth->EEECallback = HAL_ETH_EEECallback; /* Legacy weak EEECallback */
3383 heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */
3384 heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */
3385 heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */
3386 #ifdef HAL_ETH_USE_PTP
3387 heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */
3388 #endif /* HAL_ETH_USE_PTP */
3389 heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
3390 }
3391 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3392
3393 /**
3394 * @}
3395 */
3396
3397 /**
3398 * @}
3399 */
3400
3401 #endif /* ETH */
3402
3403 #endif /* HAL_ETH_MODULE_ENABLED */
3404
3405 /**
3406 * @}
3407 */
3408