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