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