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