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