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