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