Subversion Repositories dashGPS

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_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 de-initialization functions
9
  *           + IO operation functions
10
  *           + Peripheral Control functions
11
  *           + Peripheral State and Errors functions
12
  *
13
  @verbatim
14
  ==============================================================================
15
                    ##### How to use this driver #####
16
  ==============================================================================
17
    [..]
18
      (#)Declare a ETH_HandleTypeDef handle structure, for example:
19
         ETH_HandleTypeDef  heth;
20
 
21
      (#)Fill parameters of Init structure in heth handle
22
 
23
      (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
24
 
25
      (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
26
          (##) Enable the Ethernet interface clock using
27
               (+++) __HAL_RCC_ETHMAC_CLK_ENABLE();
28
               (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE();
29
               (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE();
30
 
31
          (##) Initialize the related GPIO clocks
32
          (##) Configure Ethernet pin-out
33
          (##) Configure Ethernet NVIC interrupt (IT mode)
34
 
35
      (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:
36
          (##) HAL_ETH_DMATxDescListInit(); for Transmission process
37
          (##) HAL_ETH_DMARxDescListInit(); for Reception process
38
 
39
      (#)Enable MAC and DMA transmission and reception:
40
          (##) HAL_ETH_Start();
41
 
42
      (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer
43
         the frame to MAC TX FIFO:
44
         (##) HAL_ETH_TransmitFrame();
45
 
46
      (#)Poll for a received frame in ETH RX DMA Descriptors and get received
47
         frame parameters
48
         (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)
49
 
50
      (#) Get a received frame when an ETH RX interrupt occurs:
51
         (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)
52
 
53
      (#) Communicate with external PHY device:
54
         (##) Read a specific register from the PHY
55
              HAL_ETH_ReadPHYRegister();
56
         (##) Write data to a specific RHY register:
57
              HAL_ETH_WritePHYRegister();
58
 
59
      (#) Configure the Ethernet MAC after ETH peripheral initialization
60
          HAL_ETH_ConfigMAC(); all MAC parameters should be filled.
61
 
62
      (#) Configure the Ethernet DMA after ETH peripheral initialization
63
          HAL_ETH_ConfigDMA(); all DMA parameters should be filled.
64
 
65
      -@- The PTP protocol and the DMA descriptors ring mode are not supported
66
          in this driver
67
*** Callback registration ***
68
  =============================================
69
 
70
  The compilation define  USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
71
  allows the user to configure dynamically the driver callbacks.
72
  Use Function @ref HAL_ETH_RegisterCallback() to register an interrupt callback.
73
 
74
  Function @ref HAL_ETH_RegisterCallback() allows to register following callbacks:
75
    (+) TxCpltCallback   : Tx Complete Callback.
76
    (+) RxCpltCallback   : Rx Complete Callback.
77
    (+) DMAErrorCallback : DMA Error Callback.
78
    (+) MspInitCallback  : MspInit Callback.
79
    (+) MspDeInitCallback: MspDeInit Callback.
80
 
81
  This function takes as parameters the HAL peripheral handle, the Callback ID
82
  and a pointer to the user callback function.
83
 
84
  Use function @ref HAL_ETH_UnRegisterCallback() to reset a callback to the default
85
  weak function.
86
  @ref HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
87
  and the Callback ID.
88
  This function allows to reset following callbacks:
89
    (+) TxCpltCallback   : Tx Complete Callback.
90
    (+) RxCpltCallback   : Rx Complete Callback.
91
    (+) DMAErrorCallback : DMA Error Callback.
92
    (+) MspInitCallback  : MspInit Callback.
93
    (+) MspDeInitCallback: MspDeInit Callback.
94
 
95
  By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
96
  all callbacks are set to the corresponding weak functions:
97
  examples @ref HAL_ETH_TxCpltCallback(), @ref HAL_ETH_RxCpltCallback().
98
  Exception done for MspInit and MspDeInit functions that are
99
  reset to the legacy weak function in the HAL_ETH_Init/ @ref HAL_ETH_DeInit only when
100
  these callbacks are null (not registered beforehand).
101
  if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ @ref HAL_ETH_DeInit
102
  keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
103
 
104
  Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
105
  Exception done MspInit/MspDeInit that can be registered/unregistered
106
  in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
107
  thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
108
  In that case first register the MspInit/MspDeInit user callbacks
109
  using @ref HAL_ETH_RegisterCallback() before calling @ref HAL_ETH_DeInit
110
  or HAL_ETH_Init function.
111
 
112
  When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
113
  not defined, the callback registration feature is not available and all callbacks
114
  are set to the corresponding weak functions.
115
 
116
  @endverbatim
117
  ******************************************************************************
118
  * @attention
119
  *
120
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
121
  * All rights reserved.</center></h2>
122
  *
123
  * This software component is licensed by ST under BSD 3-Clause license,
124
  * the "License"; You may not use this file except in compliance with the
125
  * License. You may obtain a copy of the License at:
126
  *                        opensource.org/licenses/BSD-3-Clause
127
  *
128
  ******************************************************************************
129
  */
130
 
131
/* Includes ------------------------------------------------------------------*/
132
#include "stm32f1xx_hal.h"
133
 
134
/** @addtogroup STM32F1xx_HAL_Driver
135
  * @{
136
  */
137
 
138
/** @defgroup ETH ETH
139
  * @brief ETH HAL module driver
140
  * @{
141
  */
142
 
143
#ifdef HAL_ETH_MODULE_ENABLED
144
 
145
#if defined (ETH)
146
 
147
/* Private typedef -----------------------------------------------------------*/
148
/* Private define ------------------------------------------------------------*/
149
/** @defgroup ETH_Private_Constants ETH Private Constants
150
  * @{
151
  */
152
#define ETH_TIMEOUT_SWRESET               500U
153
#define ETH_TIMEOUT_LINKED_STATE          5000U
154
#define ETH_TIMEOUT_AUTONEGO_COMPLETED    5000U
155
 
156
/**
157
  * @}
158
  */
159
/* Private macro -------------------------------------------------------------*/
160
/* Private variables ---------------------------------------------------------*/
161
/* Private function prototypes -----------------------------------------------*/
162
/** @defgroup ETH_Private_Functions ETH Private Functions
163
  * @{
164
  */
165
static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err);
166
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
167
static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth);
168
static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth);
169
static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth);
170
static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth);
171
static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth);
172
static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth);
173
static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth);
174
static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth);
175
static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
176
static void ETH_Delay(uint32_t mdelay);
177
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
178
static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
179
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
180
 
181
/**
182
  * @}
183
  */
184
/* Private functions ---------------------------------------------------------*/
185
 
186
/** @defgroup ETH_Exported_Functions ETH Exported Functions
187
  * @{
188
  */
189
 
190
/** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions
191
  *  @brief   Initialization and Configuration functions
192
  *
193
  @verbatim
194
  ===============================================================================
195
            ##### Initialization and de-initialization functions #####
196
  ===============================================================================
197
  [..]  This section provides functions allowing to:
198
      (+) Initialize and configure the Ethernet peripheral
199
      (+) De-initialize the Ethernet peripheral
200
 
201
  @endverbatim
202
  * @{
203
  */
204
 
205
/**
206
  * @brief  Initializes the Ethernet MAC and DMA according to default
207
  *         parameters.
208
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
209
  *         the configuration information for ETHERNET module
210
  * @retval HAL status
211
  */
212
HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
213
{
214
  uint32_t tmpreg1 = 0U, phyreg = 0U;
215
  uint32_t hclk = 60000000U;
216
  uint32_t tickstart = 0U;
217
  uint32_t err = ETH_SUCCESS;
218
 
219
  /* Check the ETH peripheral state */
220
  if (heth == NULL)
221
  {
222
    return HAL_ERROR;
223
  }
224
 
225
  /* Check parameters */
226
  assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
227
  assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
228
  assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
229
  assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
230
 
231
  if (heth->State == HAL_ETH_STATE_RESET)
232
  {
233
    /* Allocate lock resource and initialize it */
234
    heth->Lock = HAL_UNLOCKED;
235
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
236
    ETH_InitCallbacksToDefault(heth);
237
 
238
    if (heth->MspInitCallback == NULL)
239
    {
240
      /* Init the low level hardware : GPIO, CLOCK, NVIC. */
241
      heth->MspInitCallback = HAL_ETH_MspInit;
242
    }
243
    heth->MspInitCallback(heth);
244
 
245
#else
246
    /* Init the low level hardware : GPIO, CLOCK, NVIC. */
247
    HAL_ETH_MspInit(heth);
248
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
249
  }
250
 
251
  /* Select MII or RMII Mode*/
252
  AFIO->MAPR &= ~(AFIO_MAPR_MII_RMII_SEL);
253
  AFIO->MAPR |= (uint32_t)heth->Init.MediaInterface;
254
 
255
  /* Ethernet Software reset */
256
  /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
257
  /* After reset all the registers holds their respective reset values */
258
  (heth->Instance)->DMABMR |= ETH_DMABMR_SR;
259
 
260
  /* Get tick */
261
  tickstart = HAL_GetTick();
262
 
263
  /* Wait for software reset */
264
  while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
265
  {
266
    /* Check for the Timeout */
267
    if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_SWRESET)
268
    {
269
      heth->State = HAL_ETH_STATE_TIMEOUT;
270
 
271
      /* Process Unlocked */
272
      __HAL_UNLOCK(heth);
273
 
274
      /* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are
275
         not available, please check your external PHY or the IO configuration */
276
      return HAL_TIMEOUT;
277
    }
278
  }
279
 
280
  /*-------------------------------- MAC Initialization ----------------------*/
281
  /* Get the ETHERNET MACMIIAR value */
282
  tmpreg1 = (heth->Instance)->MACMIIAR;
283
  /* Clear CSR Clock Range CR[2:0] bits */
284
  tmpreg1 &= ETH_MACMIIAR_CR_MASK;
285
 
286
  /* Get hclk frequency value */
287
  hclk = HAL_RCC_GetHCLKFreq();
288
 
289
  /* Set CR bits depending on hclk value */
290
  if ((hclk >= 20000000U) && (hclk < 35000000U))
291
  {
292
    /* CSR Clock Range between 20-35 MHz */
293
    tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV16;
294
  }
295
  else if ((hclk >= 35000000U) && (hclk < 60000000U))
296
  {
297
    /* CSR Clock Range between 35-60 MHz */
298
    tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV26;
299
  }
300
  else
301
  {
302
    /* CSR Clock Range between 60-72 MHz */
303
    tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV42;
304
  }
305
 
306
  /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
307
  (heth->Instance)->MACMIIAR = (uint32_t)tmpreg1;
308
 
309
  /*-------------------- PHY initialization and configuration ----------------*/
310
  /* Put the PHY in reset mode */
311
  if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK)
312
  {
313
    /* In case of write timeout */
314
    err = ETH_ERROR;
315
 
316
    /* Config MAC and DMA */
317
    ETH_MACDMAConfig(heth, err);
318
 
319
    /* Set the ETH peripheral state to READY */
320
    heth->State = HAL_ETH_STATE_READY;
321
 
322
    /* Return HAL_ERROR */
323
    return HAL_ERROR;
324
  }
325
 
326
  /* Delay to assure PHY reset */
327
  HAL_Delay(PHY_RESET_DELAY);
328
 
329
  if ((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
330
  {
331
    /* Get tick */
332
    tickstart = HAL_GetTick();
333
 
334
    /* We wait for linked status */
335
    do
336
    {
337
      HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
338
 
339
      /* Check for the Timeout */
340
      if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_LINKED_STATE)
341
      {
342
        /* In case of write timeout */
343
        err = ETH_ERROR;
344
 
345
        /* Config MAC and DMA */
346
        ETH_MACDMAConfig(heth, err);
347
 
348
        heth->State = HAL_ETH_STATE_READY;
349
 
350
        /* Process Unlocked */
351
        __HAL_UNLOCK(heth);
352
 
353
        return HAL_TIMEOUT;
354
      }
355
    }
356
    while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));
357
 
358
 
359
    /* Enable Auto-Negotiation */
360
    if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK)
361
    {
362
      /* In case of write timeout */
363
      err = ETH_ERROR;
364
 
365
      /* Config MAC and DMA */
366
      ETH_MACDMAConfig(heth, err);
367
 
368
      /* Set the ETH peripheral state to READY */
369
      heth->State = HAL_ETH_STATE_READY;
370
 
371
      /* Return HAL_ERROR */
372
      return HAL_ERROR;
373
    }
374
 
375
    /* Get tick */
376
    tickstart = HAL_GetTick();
377
 
378
    /* Wait until the auto-negotiation will be completed */
379
    do
380
    {
381
      HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
382
 
383
      /* Check for the Timeout */
384
      if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_AUTONEGO_COMPLETED)
385
      {
386
        /* In case of write timeout */
387
        err = ETH_ERROR;
388
 
389
        /* Config MAC and DMA */
390
        ETH_MACDMAConfig(heth, err);
391
 
392
        heth->State = HAL_ETH_STATE_READY;
393
 
394
        /* Process Unlocked */
395
        __HAL_UNLOCK(heth);
396
 
397
        return HAL_TIMEOUT;
398
      }
399
 
400
    }
401
    while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
402
 
403
    /* Read the result of the auto-negotiation */
404
    if ((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK)
405
    {
406
      /* In case of write timeout */
407
      err = ETH_ERROR;
408
 
409
      /* Config MAC and DMA */
410
      ETH_MACDMAConfig(heth, err);
411
 
412
      /* Set the ETH peripheral state to READY */
413
      heth->State = HAL_ETH_STATE_READY;
414
 
415
      /* Return HAL_ERROR */
416
      return HAL_ERROR;
417
    }
418
 
419
    /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
420
    if ((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
421
    {
422
      /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
423
      (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
424
    }
425
    else
426
    {
427
      /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
428
      (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
429
    }
430
    /* Configure the MAC with the speed fixed by the auto-negotiation process */
431
    if ((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS)
432
    {
433
      /* Set Ethernet speed to 10M following the auto-negotiation */
434
      (heth->Init).Speed = ETH_SPEED_10M;
435
    }
436
    else
437
    {
438
      /* Set Ethernet speed to 100M following the auto-negotiation */
439
      (heth->Init).Speed = ETH_SPEED_100M;
440
    }
441
  }
442
  else /* AutoNegotiation Disable */
443
  {
444
    /* Check parameters */
445
    assert_param(IS_ETH_SPEED(heth->Init.Speed));
446
    assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
447
 
448
    /* Set MAC Speed and Duplex Mode */
449
    if (HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) |
450
                                                 (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK)
451
    {
452
      /* In case of write timeout */
453
      err = ETH_ERROR;
454
 
455
      /* Config MAC and DMA */
456
      ETH_MACDMAConfig(heth, err);
457
 
458
      /* Set the ETH peripheral state to READY */
459
      heth->State = HAL_ETH_STATE_READY;
460
 
461
      /* Return HAL_ERROR */
462
      return HAL_ERROR;
463
    }
464
 
465
    /* Delay to assure PHY configuration */
466
    HAL_Delay(PHY_CONFIG_DELAY);
467
  }
468
 
469
  /* Config MAC and DMA */
470
  ETH_MACDMAConfig(heth, err);
471
 
472
  /* Set ETH HAL State to Ready */
473
  heth->State = HAL_ETH_STATE_READY;
474
 
475
  /* Return function status */
476
  return HAL_OK;
477
}
478
 
479
/**
480
  * @brief  De-Initializes the ETH peripheral.
481
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
482
  *         the configuration information for ETHERNET module
483
  * @retval HAL status
484
  */
485
HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
486
{
487
  /* Set the ETH peripheral state to BUSY */
488
  heth->State = HAL_ETH_STATE_BUSY;
489
 
490
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
491
  if (heth->MspDeInitCallback == NULL)
492
  {
493
    heth->MspDeInitCallback = HAL_ETH_MspDeInit;
494
  }
495
  /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
496
  heth->MspDeInitCallback(heth);
497
#else
498
  /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
499
  HAL_ETH_MspDeInit(heth);
500
#endif
501
 
502
  /* Set ETH HAL state to Disabled */
503
  heth->State = HAL_ETH_STATE_RESET;
504
 
505
  /* Release Lock */
506
  __HAL_UNLOCK(heth);
507
 
508
  /* Return function status */
509
  return HAL_OK;
510
}
511
 
512
/**
513
  * @brief  Initializes the DMA Tx descriptors in chain mode.
514
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
515
  *         the configuration information for ETHERNET module
516
  * @param  DMATxDescTab: Pointer to the first Tx desc list
517
  * @param  TxBuff: Pointer to the first TxBuffer list
518
  * @param  TxBuffCount: Number of the used Tx desc in the list
519
  * @retval HAL status
520
  */
521
HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount)
522
{
523
  uint32_t i = 0U;
524
  ETH_DMADescTypeDef *dmatxdesc;
525
 
526
  /* Process Locked */
527
  __HAL_LOCK(heth);
528
 
529
  /* Set the ETH peripheral state to BUSY */
530
  heth->State = HAL_ETH_STATE_BUSY;
531
 
532
  /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */
533
  heth->TxDesc = DMATxDescTab;
534
 
535
  /* Fill each DMATxDesc descriptor with the right values */
536
  for (i = 0U; i < TxBuffCount; i++)
537
  {
538
    /* Get the pointer on the ith member of the Tx Desc list */
539
    dmatxdesc = DMATxDescTab + i;
540
 
541
    /* Set Second Address Chained bit */
542
    dmatxdesc->Status = ETH_DMATXDESC_TCH;
543
 
544
    /* Set Buffer1 address pointer */
545
    dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i * ETH_TX_BUF_SIZE]);
546
 
547
    if ((heth->Init).ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
548
    {
549
      /* Set the DMA Tx descriptors checksum insertion */
550
      dmatxdesc->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
551
    }
552
 
553
    /* Initialize the next descriptor with the Next Descriptor Polling Enable */
554
    if (i < (TxBuffCount - 1U))
555
    {
556
      /* Set next descriptor address register with next descriptor base address */
557
      dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + i + 1U);
558
    }
559
    else
560
    {
561
      /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
562
      dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
563
    }
564
  }
565
 
566
  /* Set Transmit Descriptor List Address Register */
567
  (heth->Instance)->DMATDLAR = (uint32_t) DMATxDescTab;
568
 
569
  /* Set ETH HAL State to Ready */
570
  heth->State = HAL_ETH_STATE_READY;
571
 
572
  /* Process Unlocked */
573
  __HAL_UNLOCK(heth);
574
 
575
  /* Return function status */
576
  return HAL_OK;
577
}
578
 
579
/**
580
  * @brief  Initializes the DMA Rx descriptors in chain mode.
581
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
582
  *         the configuration information for ETHERNET module
583
  * @param  DMARxDescTab: Pointer to the first Rx desc list
584
  * @param  RxBuff: Pointer to the first RxBuffer list
585
  * @param  RxBuffCount: Number of the used Rx desc in the list
586
  * @retval HAL status
587
  */
588
HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
589
{
590
  uint32_t i = 0U;
591
  ETH_DMADescTypeDef *DMARxDesc;
592
 
593
  /* Process Locked */
594
  __HAL_LOCK(heth);
595
 
596
  /* Set the ETH peripheral state to BUSY */
597
  heth->State = HAL_ETH_STATE_BUSY;
598
 
599
  /* Set the Ethernet RxDesc pointer with the first one of the DMARxDescTab list */
600
  heth->RxDesc = DMARxDescTab;
601
 
602
  /* Fill each DMARxDesc descriptor with the right values */
603
  for (i = 0U; i < RxBuffCount; i++)
604
  {
605
    /* Get the pointer on the ith member of the Rx Desc list */
606
    DMARxDesc = DMARxDescTab + i;
607
 
608
    /* Set Own bit of the Rx descriptor Status */
609
    DMARxDesc->Status = ETH_DMARXDESC_OWN;
610
 
611
    /* Set Buffer1 size and Second Address Chained bit */
612
    DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
613
 
614
    /* Set Buffer1 address pointer */
615
    DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_RX_BUF_SIZE]);
616
 
617
    if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
618
    {
619
      /* Enable Ethernet DMA Rx Descriptor interrupt */
620
      DMARxDesc->ControlBufferSize &= ~ETH_DMARXDESC_DIC;
621
    }
622
 
623
    /* Initialize the next descriptor with the Next Descriptor Polling Enable */
624
    if (i < (RxBuffCount - 1U))
625
    {
626
      /* Set next descriptor address register with next descriptor base address */
627
      DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1U);
628
    }
629
    else
630
    {
631
      /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
632
      DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
633
    }
634
  }
635
 
636
  /* Set Receive Descriptor List Address Register */
637
  (heth->Instance)->DMARDLAR = (uint32_t) DMARxDescTab;
638
 
639
  /* Set ETH HAL State to Ready */
640
  heth->State = HAL_ETH_STATE_READY;
641
 
642
  /* Process Unlocked */
643
  __HAL_UNLOCK(heth);
644
 
645
  /* Return function status */
646
  return HAL_OK;
647
}
648
 
649
/**
650
  * @brief  Initializes the ETH MSP.
651
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
652
  *         the configuration information for ETHERNET module
653
  * @retval None
654
  */
655
__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
656
{
657
  /* Prevent unused argument(s) compilation warning */
658
  UNUSED(heth);
659
  /* NOTE : This function Should not be modified, when the callback is needed,
660
  the HAL_ETH_MspInit could be implemented in the user file
661
  */
662
}
663
 
664
/**
665
  * @brief  DeInitializes ETH MSP.
666
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
667
  *         the configuration information for ETHERNET module
668
  * @retval None
669
  */
670
__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
671
{
672
  /* Prevent unused argument(s) compilation warning */
673
  UNUSED(heth);
674
  /* NOTE : This function Should not be modified, when the callback is needed,
675
  the HAL_ETH_MspDeInit could be implemented in the user file
676
  */
677
}
678
 
679
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
680
/**
681
  * @brief  Register a User ETH Callback
682
  *         To be used instead of the weak predefined callback
683
  * @param heth eth handle
684
  * @param CallbackID ID of the callback to be registered
685
  *        This parameter can be one of the following values:
686
  *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
687
  *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
688
  *          @arg @ref HAL_ETH_DMA_ERROR_CB_ID   DMA Error Callback ID
689
  *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
690
  *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
691
  * @param pCallback pointer to the Callback function
692
  * @retval status
693
  */
694
HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, pETH_CallbackTypeDef pCallback)
695
{
696
  HAL_StatusTypeDef status = HAL_OK;
697
 
698
  if (pCallback == NULL)
699
  {
700
    return HAL_ERROR;
701
  }
702
  /* Process locked */
703
  __HAL_LOCK(heth);
704
 
705
  if (heth->State == HAL_ETH_STATE_READY)
706
  {
707
    switch (CallbackID)
708
    {
709
      case HAL_ETH_TX_COMPLETE_CB_ID :
710
        heth->TxCpltCallback = pCallback;
711
        break;
712
 
713
      case HAL_ETH_RX_COMPLETE_CB_ID :
714
        heth->RxCpltCallback = pCallback;
715
        break;
716
 
717
      case HAL_ETH_DMA_ERROR_CB_ID :
718
        heth->DMAErrorCallback = pCallback;
719
        break;
720
 
721
      case HAL_ETH_MSPINIT_CB_ID :
722
        heth->MspInitCallback = pCallback;
723
        break;
724
 
725
      case HAL_ETH_MSPDEINIT_CB_ID :
726
        heth->MspDeInitCallback = pCallback;
727
        break;
728
 
729
      default :
730
        /* Return error status */
731
        status =  HAL_ERROR;
732
        break;
733
    }
734
  }
735
  else if (heth->State == HAL_ETH_STATE_RESET)
736
  {
737
    switch (CallbackID)
738
    {
739
      case HAL_ETH_MSPINIT_CB_ID :
740
        heth->MspInitCallback = pCallback;
741
        break;
742
 
743
      case HAL_ETH_MSPDEINIT_CB_ID :
744
        heth->MspDeInitCallback = pCallback;
745
        break;
746
 
747
      default :
748
        /* Return error status */
749
        status =  HAL_ERROR;
750
        break;
751
    }
752
  }
753
  else
754
  {
755
    /* Return error status */
756
    status =  HAL_ERROR;
757
  }
758
 
759
  /* Release Lock */
760
  __HAL_UNLOCK(heth);
761
 
762
  return status;
763
}
764
 
765
/**
766
  * @brief  Unregister an ETH Callback
767
  *         ETH callabck is redirected to the weak predefined callback
768
  * @param heth eth handle
769
  * @param CallbackID ID of the callback to be unregistered
770
  *        This parameter can be one of the following values:
771
  *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
772
  *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
773
  *          @arg @ref HAL_ETH_DMA_ERROR_CB_ID      DMA Error Callback ID
774
  *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
775
  *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
776
  * @retval status
777
  */
778
HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
779
{
780
  HAL_StatusTypeDef status = HAL_OK;
781
 
782
  /* Process locked */
783
  __HAL_LOCK(heth);
784
 
785
  if (heth->State == HAL_ETH_STATE_READY)
786
  {
787
    switch (CallbackID)
788
    {
789
      case HAL_ETH_TX_COMPLETE_CB_ID :
790
        heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
791
        break;
792
 
793
      case HAL_ETH_RX_COMPLETE_CB_ID :
794
        heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
795
        break;
796
 
797
      case HAL_ETH_DMA_ERROR_CB_ID :
798
        heth->DMAErrorCallback = HAL_ETH_ErrorCallback;
799
        break;
800
 
801
      case HAL_ETH_MSPINIT_CB_ID :
802
        heth->MspInitCallback = HAL_ETH_MspInit;
803
        break;
804
 
805
      case HAL_ETH_MSPDEINIT_CB_ID :
806
        heth->MspDeInitCallback = HAL_ETH_MspDeInit;
807
        break;
808
 
809
      default :
810
        /* Return error status */
811
        status =  HAL_ERROR;
812
        break;
813
    }
814
  }
815
  else if (heth->State == HAL_ETH_STATE_RESET)
816
  {
817
    switch (CallbackID)
818
    {
819
      case HAL_ETH_MSPINIT_CB_ID :
820
        heth->MspInitCallback = HAL_ETH_MspInit;
821
        break;
822
 
823
      case HAL_ETH_MSPDEINIT_CB_ID :
824
        heth->MspDeInitCallback = HAL_ETH_MspDeInit;
825
        break;
826
 
827
      default :
828
        /* Return error status */
829
        status =  HAL_ERROR;
830
        break;
831
    }
832
  }
833
  else
834
  {
835
    /* Return error status */
836
    status =  HAL_ERROR;
837
  }
838
 
839
  /* Release Lock */
840
  __HAL_UNLOCK(heth);
841
 
842
  return status;
843
}
844
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
845
 
846
/**
847
  * @}
848
  */
849
 
850
/** @defgroup ETH_Exported_Functions_Group2 IO operation functions
851
  *  @brief   Data transfers functions
852
  *
853
  @verbatim
854
  ==============================================================================
855
                          ##### IO operation functions #####
856
  ==============================================================================
857
  [..]  This section provides functions allowing to:
858
        (+) Transmit a frame
859
            HAL_ETH_TransmitFrame();
860
        (+) Receive a frame
861
            HAL_ETH_GetReceivedFrame();
862
            HAL_ETH_GetReceivedFrame_IT();
863
        (+) Read from an External PHY register
864
            HAL_ETH_ReadPHYRegister();
865
        (+) Write to an External PHY register
866
            HAL_ETH_WritePHYRegister();
867
 
868
  @endverbatim
869
 
870
  * @{
871
  */
872
 
873
/**
874
  * @brief  Sends an Ethernet frame.
875
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
876
  *         the configuration information for ETHERNET module
877
  * @param  FrameLength: Amount of data to be sent
878
  * @retval HAL status
879
  */
880
HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
881
{
882
  uint32_t bufcount = 0U, size = 0U, i = 0U;
883
 
884
  /* Process Locked */
885
  __HAL_LOCK(heth);
886
 
887
  /* Set the ETH peripheral state to BUSY */
888
  heth->State = HAL_ETH_STATE_BUSY;
889
 
890
  if (FrameLength == 0U)
891
  {
892
    /* Set ETH HAL state to READY */
893
    heth->State = HAL_ETH_STATE_READY;
894
 
895
    /* Process Unlocked */
896
    __HAL_UNLOCK(heth);
897
 
898
    return  HAL_ERROR;
899
  }
900
 
901
  /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
902
  if (((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
903
  {
904
    /* OWN bit set */
905
    heth->State = HAL_ETH_STATE_BUSY_TX;
906
 
907
    /* Process Unlocked */
908
    __HAL_UNLOCK(heth);
909
 
910
    return HAL_ERROR;
911
  }
912
 
913
  /* Get the number of needed Tx buffers for the current frame */
914
  if (FrameLength > ETH_TX_BUF_SIZE)
915
  {
916
    bufcount = FrameLength / ETH_TX_BUF_SIZE;
917
    if (FrameLength % ETH_TX_BUF_SIZE)
918
    {
919
      bufcount++;
920
    }
921
  }
922
  else
923
  {
924
    bufcount = 1U;
925
  }
926
  if (bufcount == 1U)
927
  {
928
    /* Set LAST and FIRST segment */
929
    heth->TxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
930
    /* Set frame size */
931
    heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1);
932
    /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
933
    heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
934
    /* Point to next descriptor */
935
    heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
936
  }
937
  else
938
  {
939
    for (i = 0U; i < bufcount; i++)
940
    {
941
      /* Clear FIRST and LAST segment bits */
942
      heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
943
 
944
      if (i == 0U)
945
      {
946
        /* Setting the first segment bit */
947
        heth->TxDesc->Status |= ETH_DMATXDESC_FS;
948
      }
949
 
950
      /* Program size */
951
      heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
952
 
953
      if (i == (bufcount - 1U))
954
      {
955
        /* Setting the last segment bit */
956
        heth->TxDesc->Status |= ETH_DMATXDESC_LS;
957
        size = FrameLength - (bufcount - 1U) * ETH_TX_BUF_SIZE;
958
        heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
959
      }
960
 
961
      /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
962
      heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
963
      /* point to next descriptor */
964
      heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
965
    }
966
  }
967
 
968
  /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
969
  if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
970
  {
971
    /* Clear TBUS ETHERNET DMA flag */
972
    (heth->Instance)->DMASR = ETH_DMASR_TBUS;
973
    /* Resume DMA transmission*/
974
    (heth->Instance)->DMATPDR = 0U;
975
  }
976
 
977
  /* Set ETH HAL State to Ready */
978
  heth->State = HAL_ETH_STATE_READY;
979
 
980
  /* Process Unlocked */
981
  __HAL_UNLOCK(heth);
982
 
983
  /* Return function status */
984
  return HAL_OK;
985
}
986
 
987
/**
988
  * @brief  Checks for received frames.
989
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
990
  *         the configuration information for ETHERNET module
991
  * @retval HAL status
992
  */
993
HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth)
994
{
995
  uint32_t framelength = 0U;
996
 
997
  /* Process Locked */
998
  __HAL_LOCK(heth);
999
 
1000
  /* Check the ETH state to BUSY */
1001
  heth->State = HAL_ETH_STATE_BUSY;
1002
 
1003
  /* Check if segment is not owned by DMA */
1004
  /* (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) */
1005
  if (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET))
1006
  {
1007
    /* Check if last segment */
1008
    if (((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET))
1009
    {
1010
      /* increment segment count */
1011
      (heth->RxFrameInfos).SegCount++;
1012
 
1013
      /* Check if last segment is first segment: one segment contains the frame */
1014
      if ((heth->RxFrameInfos).SegCount == 1U)
1015
      {
1016
        (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
1017
      }
1018
 
1019
      heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
1020
 
1021
      /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
1022
      framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
1023
      heth->RxFrameInfos.length = framelength;
1024
 
1025
      /* Get the address of the buffer start address */
1026
      heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
1027
      /* point to next descriptor */
1028
      heth->RxDesc = (ETH_DMADescTypeDef *)((heth->RxDesc)->Buffer2NextDescAddr);
1029
 
1030
      /* Set HAL State to Ready */
1031
      heth->State = HAL_ETH_STATE_READY;
1032
 
1033
      /* Process Unlocked */
1034
      __HAL_UNLOCK(heth);
1035
 
1036
      /* Return function status */
1037
      return HAL_OK;
1038
    }
1039
    /* Check if first segment */
1040
    else if ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET)
1041
    {
1042
      (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
1043
      (heth->RxFrameInfos).LSRxDesc = NULL;
1044
      (heth->RxFrameInfos).SegCount = 1U;
1045
      /* Point to next descriptor */
1046
      heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1047
    }
1048
    /* Check if intermediate segment */
1049
    else
1050
    {
1051
      (heth->RxFrameInfos).SegCount++;
1052
      /* Point to next descriptor */
1053
      heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1054
    }
1055
  }
1056
 
1057
  /* Set ETH HAL State to Ready */
1058
  heth->State = HAL_ETH_STATE_READY;
1059
 
1060
  /* Process Unlocked */
1061
  __HAL_UNLOCK(heth);
1062
 
1063
  /* Return function status */
1064
  return HAL_ERROR;
1065
}
1066
 
1067
/**
1068
  * @brief  Gets the Received frame in interrupt mode.
1069
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1070
  *         the configuration information for ETHERNET module
1071
  * @retval HAL status
1072
  */
1073
HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth)
1074
{
1075
  uint32_t descriptorscancounter = 0U;
1076
 
1077
  /* Process Locked */
1078
  __HAL_LOCK(heth);
1079
 
1080
  /* Set ETH HAL State to BUSY */
1081
  heth->State = HAL_ETH_STATE_BUSY;
1082
 
1083
  /* Scan descriptors owned by CPU */
1084
  while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (descriptorscancounter < ETH_RXBUFNB))
1085
  {
1086
    /* Just for security */
1087
    descriptorscancounter++;
1088
 
1089
    /* Check if first segment in frame */
1090
    /* ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)) */
1091
    if ((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == (uint32_t)ETH_DMARXDESC_FS)
1092
    {
1093
      heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
1094
      heth->RxFrameInfos.SegCount = 1U;
1095
      /* Point to next descriptor */
1096
      heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1097
    }
1098
    /* Check if intermediate segment */
1099
    /* ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)&& ((heth->RxDesc->Status & ETH_DMARXDESC_FS) == (uint32_t)RESET)) */
1100
    else if ((heth->RxDesc->Status & (ETH_DMARXDESC_LS | ETH_DMARXDESC_FS)) == (uint32_t)RESET)
1101
    {
1102
      /* Increment segment count */
1103
      (heth->RxFrameInfos.SegCount)++;
1104
      /* Point to next descriptor */
1105
      heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1106
    }
1107
    /* Should be last segment */
1108
    else
1109
    {
1110
      /* Last segment */
1111
      heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
1112
 
1113
      /* Increment segment count */
1114
      (heth->RxFrameInfos.SegCount)++;
1115
 
1116
      /* Check if last segment is first segment: one segment contains the frame */
1117
      if ((heth->RxFrameInfos.SegCount) == 1U)
1118
      {
1119
        heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
1120
      }
1121
 
1122
      /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
1123
      heth->RxFrameInfos.length = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
1124
 
1125
      /* Get the address of the buffer start address */
1126
      heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
1127
 
1128
      /* Point to next descriptor */
1129
      heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
1130
 
1131
      /* Set HAL State to Ready */
1132
      heth->State = HAL_ETH_STATE_READY;
1133
 
1134
      /* Process Unlocked */
1135
      __HAL_UNLOCK(heth);
1136
 
1137
      /* Return function status */
1138
      return HAL_OK;
1139
    }
1140
  }
1141
 
1142
  /* Set HAL State to Ready */
1143
  heth->State = HAL_ETH_STATE_READY;
1144
 
1145
  /* Process Unlocked */
1146
  __HAL_UNLOCK(heth);
1147
 
1148
  /* Return function status */
1149
  return HAL_ERROR;
1150
}
1151
 
1152
/**
1153
  * @brief  This function handles ETH interrupt request.
1154
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1155
  *         the configuration information for ETHERNET module
1156
  * @retval HAL status
1157
  */
1158
void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1159
{
1160
  /* Frame received */
1161
  if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R))
1162
  {
1163
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1164
    /*Call registered Receive complete callback*/
1165
    heth->RxCpltCallback(heth);
1166
#else
1167
    /* Receive complete callback */
1168
    HAL_ETH_RxCpltCallback(heth);
1169
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1170
 
1171
    /* Clear the Eth DMA Rx IT pending bits */
1172
    __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R);
1173
 
1174
    /* Set HAL State to Ready */
1175
    heth->State = HAL_ETH_STATE_READY;
1176
 
1177
    /* Process Unlocked */
1178
    __HAL_UNLOCK(heth);
1179
 
1180
  }
1181
  /* Frame transmitted */
1182
  else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T))
1183
  {
1184
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1185
    /*  Call resgistered Transfer complete callback*/
1186
    heth->TxCpltCallback(heth);
1187
#else
1188
    /* Transfer complete callback */
1189
    HAL_ETH_TxCpltCallback(heth);
1190
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1191
 
1192
    /* Clear the Eth DMA Tx IT pending bits */
1193
    __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T);
1194
 
1195
    /* Set HAL State to Ready */
1196
    heth->State = HAL_ETH_STATE_READY;
1197
 
1198
    /* Process Unlocked */
1199
    __HAL_UNLOCK(heth);
1200
  }
1201
 
1202
  /* Clear the interrupt flags */
1203
  __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS);
1204
 
1205
  /* ETH DMA Error */
1206
  if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS))
1207
  {
1208
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1209
    heth->DMAErrorCallback(heth);
1210
#else
1211
    /* Ethernet Error callback */
1212
    HAL_ETH_ErrorCallback(heth);
1213
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
1214
 
1215
    /* Clear the interrupt flags */
1216
    __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS);
1217
 
1218
    /* Set HAL State to Ready */
1219
    heth->State = HAL_ETH_STATE_READY;
1220
 
1221
    /* Process Unlocked */
1222
    __HAL_UNLOCK(heth);
1223
  }
1224
}
1225
 
1226
/**
1227
  * @brief  Tx Transfer completed callbacks.
1228
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1229
  *         the configuration information for ETHERNET module
1230
  * @retval None
1231
  */
1232
__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
1233
{
1234
  /* Prevent unused argument(s) compilation warning */
1235
  UNUSED(heth);
1236
  /* NOTE : This function Should not be modified, when the callback is needed,
1237
  the HAL_ETH_TxCpltCallback could be implemented in the user file
1238
  */
1239
}
1240
 
1241
/**
1242
  * @brief  Rx Transfer completed callbacks.
1243
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1244
  *         the configuration information for ETHERNET module
1245
  * @retval None
1246
  */
1247
__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
1248
{
1249
  /* Prevent unused argument(s) compilation warning */
1250
  UNUSED(heth);
1251
  /* NOTE : This function Should not be modified, when the callback is needed,
1252
  the HAL_ETH_TxCpltCallback could be implemented in the user file
1253
  */
1254
}
1255
 
1256
/**
1257
  * @brief  Ethernet transfer error callbacks
1258
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1259
  *         the configuration information for ETHERNET module
1260
  * @retval None
1261
  */
1262
__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
1263
{
1264
  /* Prevent unused argument(s) compilation warning */
1265
  UNUSED(heth);
1266
  /* NOTE : This function Should not be modified, when the callback is needed,
1267
  the HAL_ETH_TxCpltCallback could be implemented in the user file
1268
  */
1269
}
1270
 
1271
/**
1272
  * @brief  Reads a PHY register
1273
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1274
  *         the configuration information for ETHERNET module
1275
  * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
1276
  *                This parameter can be one of the following values:
1277
  *                   PHY_BCR: Transceiver Basic Control Register,
1278
  *                   PHY_BSR: Transceiver Basic Status Register.
1279
  *                   More PHY register could be read depending on the used PHY
1280
  * @param RegValue: PHY register value
1281
  * @retval HAL status
1282
  */
1283
HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
1284
{
1285
  uint32_t tmpreg1 = 0U;
1286
  uint32_t tickstart = 0U;
1287
 
1288
  /* Check parameters */
1289
  assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
1290
 
1291
  /* Check the ETH peripheral state */
1292
  if (heth->State == HAL_ETH_STATE_BUSY_RD)
1293
  {
1294
    return HAL_BUSY;
1295
  }
1296
  /* Set ETH HAL State to BUSY_RD */
1297
  heth->State = HAL_ETH_STATE_BUSY_RD;
1298
 
1299
  /* Get the ETHERNET MACMIIAR value */
1300
  tmpreg1 = heth->Instance->MACMIIAR;
1301
 
1302
  /* Keep only the CSR Clock Range CR[2:0] bits value */
1303
  tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
1304
 
1305
  /* Prepare the MII address register value */
1306
  tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address   */
1307
  tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR);                /* Set the PHY register address */
1308
  tmpreg1 &= ~ETH_MACMIIAR_MW;                                            /* Set the read mode            */
1309
  tmpreg1 |= ETH_MACMIIAR_MB;                                             /* Set the MII Busy bit         */
1310
 
1311
  /* Write the result value into the MII Address register */
1312
  heth->Instance->MACMIIAR = tmpreg1;
1313
 
1314
  /* Get tick */
1315
  tickstart = HAL_GetTick();
1316
 
1317
  /* Check for the Busy flag */
1318
  while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
1319
  {
1320
    /* Check for the Timeout */
1321
    if ((HAL_GetTick() - tickstart) > PHY_READ_TO)
1322
    {
1323
      heth->State = HAL_ETH_STATE_READY;
1324
 
1325
      /* Process Unlocked */
1326
      __HAL_UNLOCK(heth);
1327
 
1328
      return HAL_TIMEOUT;
1329
    }
1330
 
1331
    tmpreg1 = heth->Instance->MACMIIAR;
1332
  }
1333
 
1334
  /* Get MACMIIDR value */
1335
  *RegValue = (uint16_t)(heth->Instance->MACMIIDR);
1336
 
1337
  /* Set ETH HAL State to READY */
1338
  heth->State = HAL_ETH_STATE_READY;
1339
 
1340
  /* Return function status */
1341
  return HAL_OK;
1342
}
1343
 
1344
/**
1345
  * @brief  Writes to a PHY register.
1346
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1347
  *         the configuration information for ETHERNET module
1348
  * @param  PHYReg: PHY register address, is the index of one of the 32 PHY register.
1349
  *          This parameter can be one of the following values:
1350
  *             PHY_BCR: Transceiver Control Register.
1351
  *             More PHY register could be written depending on the used PHY
1352
  * @param  RegValue: the value to write
1353
  * @retval HAL status
1354
  */
1355
HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
1356
{
1357
  uint32_t tmpreg1 = 0U;
1358
  uint32_t tickstart = 0U;
1359
 
1360
  /* Check parameters */
1361
  assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
1362
 
1363
  /* Check the ETH peripheral state */
1364
  if (heth->State == HAL_ETH_STATE_BUSY_WR)
1365
  {
1366
    return HAL_BUSY;
1367
  }
1368
  /* Set ETH HAL State to BUSY_WR */
1369
  heth->State = HAL_ETH_STATE_BUSY_WR;
1370
 
1371
  /* Get the ETHERNET MACMIIAR value */
1372
  tmpreg1 = heth->Instance->MACMIIAR;
1373
 
1374
  /* Keep only the CSR Clock Range CR[2:0] bits value */
1375
  tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
1376
 
1377
  /* Prepare the MII register address value */
1378
  tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
1379
  tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR);              /* Set the PHY register address */
1380
  tmpreg1 |= ETH_MACMIIAR_MW;                                           /* Set the write mode */
1381
  tmpreg1 |= ETH_MACMIIAR_MB;                                           /* Set the MII Busy bit */
1382
 
1383
  /* Give the value to the MII data register */
1384
  heth->Instance->MACMIIDR = (uint16_t)RegValue;
1385
 
1386
  /* Write the result value into the MII Address register */
1387
  heth->Instance->MACMIIAR = tmpreg1;
1388
 
1389
  /* Get tick */
1390
  tickstart = HAL_GetTick();
1391
 
1392
  /* Check for the Busy flag */
1393
  while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
1394
  {
1395
    /* Check for the Timeout */
1396
    if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO)
1397
    {
1398
      heth->State = HAL_ETH_STATE_READY;
1399
 
1400
      /* Process Unlocked */
1401
      __HAL_UNLOCK(heth);
1402
 
1403
      return HAL_TIMEOUT;
1404
    }
1405
 
1406
    tmpreg1 = heth->Instance->MACMIIAR;
1407
  }
1408
 
1409
  /* Set ETH HAL State to READY */
1410
  heth->State = HAL_ETH_STATE_READY;
1411
 
1412
  /* Return function status */
1413
  return HAL_OK;
1414
}
1415
 
1416
/**
1417
  * @}
1418
  */
1419
 
1420
/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
1421
 *  @brief    Peripheral Control functions
1422
 *
1423
@verbatim
1424
 ===============================================================================
1425
                  ##### Peripheral Control functions #####
1426
 ===============================================================================
1427
    [..]  This section provides functions allowing to:
1428
      (+) Enable MAC and DMA transmission and reception.
1429
          HAL_ETH_Start();
1430
      (+) Disable MAC and DMA transmission and reception.
1431
          HAL_ETH_Stop();
1432
      (+) Set the MAC configuration in runtime mode
1433
          HAL_ETH_ConfigMAC();
1434
      (+) Set the DMA configuration in runtime mode
1435
          HAL_ETH_ConfigDMA();
1436
 
1437
@endverbatim
1438
  * @{
1439
  */
1440
 
1441
/**
1442
 * @brief  Enables Ethernet MAC and DMA reception/transmission
1443
 * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1444
 *         the configuration information for ETHERNET module
1445
 * @retval HAL status
1446
 */
1447
HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
1448
{
1449
  /* Process Locked */
1450
  __HAL_LOCK(heth);
1451
 
1452
  /* Set the ETH peripheral state to BUSY */
1453
  heth->State = HAL_ETH_STATE_BUSY;
1454
 
1455
  /* Enable transmit state machine of the MAC for transmission on the MII */
1456
  ETH_MACTransmissionEnable(heth);
1457
 
1458
  /* Enable receive state machine of the MAC for reception from the MII */
1459
  ETH_MACReceptionEnable(heth);
1460
 
1461
  /* Flush Transmit FIFO */
1462
  ETH_FlushTransmitFIFO(heth);
1463
 
1464
  /* Start DMA transmission */
1465
  ETH_DMATransmissionEnable(heth);
1466
 
1467
  /* Start DMA reception */
1468
  ETH_DMAReceptionEnable(heth);
1469
 
1470
  /* Set the ETH state to READY*/
1471
  heth->State = HAL_ETH_STATE_READY;
1472
 
1473
  /* Process Unlocked */
1474
  __HAL_UNLOCK(heth);
1475
 
1476
  /* Return function status */
1477
  return HAL_OK;
1478
}
1479
 
1480
/**
1481
  * @brief  Stop Ethernet MAC and DMA reception/transmission
1482
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1483
  *         the configuration information for ETHERNET module
1484
  * @retval HAL status
1485
  */
1486
HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
1487
{
1488
  /* Process Locked */
1489
  __HAL_LOCK(heth);
1490
 
1491
  /* Set the ETH peripheral state to BUSY */
1492
  heth->State = HAL_ETH_STATE_BUSY;
1493
 
1494
  /* Stop DMA transmission */
1495
  ETH_DMATransmissionDisable(heth);
1496
 
1497
  /* Stop DMA reception */
1498
  ETH_DMAReceptionDisable(heth);
1499
 
1500
  /* Disable receive state machine of the MAC for reception from the MII */
1501
  ETH_MACReceptionDisable(heth);
1502
 
1503
  /* Flush Transmit FIFO */
1504
  ETH_FlushTransmitFIFO(heth);
1505
 
1506
  /* Disable transmit state machine of the MAC for transmission on the MII */
1507
  ETH_MACTransmissionDisable(heth);
1508
 
1509
  /* Set the ETH state*/
1510
  heth->State = HAL_ETH_STATE_READY;
1511
 
1512
  /* Process Unlocked */
1513
  __HAL_UNLOCK(heth);
1514
 
1515
  /* Return function status */
1516
  return HAL_OK;
1517
}
1518
 
1519
/**
1520
  * @brief  Set ETH MAC Configuration.
1521
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1522
  *         the configuration information for ETHERNET module
1523
  * @param  macconf: MAC Configuration structure
1524
  * @retval HAL status
1525
  */
1526
HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
1527
{
1528
  uint32_t tmpreg1 = 0U;
1529
 
1530
  /* Process Locked */
1531
  __HAL_LOCK(heth);
1532
 
1533
  /* Set the ETH peripheral state to BUSY */
1534
  heth->State = HAL_ETH_STATE_BUSY;
1535
 
1536
  assert_param(IS_ETH_SPEED(heth->Init.Speed));
1537
  assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
1538
 
1539
  if (macconf != NULL)
1540
  {
1541
    /* Check the parameters */
1542
    assert_param(IS_ETH_WATCHDOG(macconf->Watchdog));
1543
    assert_param(IS_ETH_JABBER(macconf->Jabber));
1544
    assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap));
1545
    assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense));
1546
    assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn));
1547
    assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode));
1548
    assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload));
1549
    assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission));
1550
    assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip));
1551
    assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit));
1552
    assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck));
1553
    assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll));
1554
    assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter));
1555
    assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames));
1556
    assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception));
1557
    assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter));
1558
    assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode));
1559
    assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter));
1560
    assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter));
1561
    assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime));
1562
    assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause));
1563
    assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold));
1564
    assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect));
1565
    assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl));
1566
    assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl));
1567
    assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison));
1568
    assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier));
1569
 
1570
    /*------------------------ ETHERNET MACCR Configuration --------------------*/
1571
    /* Get the ETHERNET MACCR value */
1572
    tmpreg1 = (heth->Instance)->MACCR;
1573
    /* Clear WD, PCE, PS, TE and RE bits */
1574
    tmpreg1 &= ETH_MACCR_CLEAR_MASK;
1575
 
1576
    tmpreg1 |= (uint32_t)(macconf->Watchdog |
1577
                          macconf->Jabber |
1578
                          macconf->InterFrameGap |
1579
                          macconf->CarrierSense |
1580
                          (heth->Init).Speed |
1581
                          macconf->ReceiveOwn |
1582
                          macconf->LoopbackMode |
1583
                          (heth->Init).DuplexMode |
1584
                          macconf->ChecksumOffload |
1585
                          macconf->RetryTransmission |
1586
                          macconf->AutomaticPadCRCStrip |
1587
                          macconf->BackOffLimit |
1588
                          macconf->DeferralCheck);
1589
 
1590
    /* Write to ETHERNET MACCR */
1591
    (heth->Instance)->MACCR = (uint32_t)tmpreg1;
1592
 
1593
    /* Wait until the write operation will be taken into account :
1594
    at least four TX_CLK/RX_CLK clock cycles */
1595
    tmpreg1 = (heth->Instance)->MACCR;
1596
    HAL_Delay(ETH_REG_WRITE_DELAY);
1597
    (heth->Instance)->MACCR = tmpreg1;
1598
 
1599
    /*----------------------- ETHERNET MACFFR Configuration --------------------*/
1600
    /* Write to ETHERNET MACFFR */
1601
    (heth->Instance)->MACFFR = (uint32_t)(macconf->ReceiveAll |
1602
                                          macconf->SourceAddrFilter |
1603
                                          macconf->PassControlFrames |
1604
                                          macconf->BroadcastFramesReception |
1605
                                          macconf->DestinationAddrFilter |
1606
                                          macconf->PromiscuousMode |
1607
                                          macconf->MulticastFramesFilter |
1608
                                          macconf->UnicastFramesFilter);
1609
 
1610
    /* Wait until the write operation will be taken into account :
1611
    at least four TX_CLK/RX_CLK clock cycles */
1612
    tmpreg1 = (heth->Instance)->MACFFR;
1613
    HAL_Delay(ETH_REG_WRITE_DELAY);
1614
    (heth->Instance)->MACFFR = tmpreg1;
1615
 
1616
    /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
1617
    /* Write to ETHERNET MACHTHR */
1618
    (heth->Instance)->MACHTHR = (uint32_t)macconf->HashTableHigh;
1619
 
1620
    /* Write to ETHERNET MACHTLR */
1621
    (heth->Instance)->MACHTLR = (uint32_t)macconf->HashTableLow;
1622
    /*----------------------- ETHERNET MACFCR Configuration --------------------*/
1623
 
1624
    /* Get the ETHERNET MACFCR value */
1625
    tmpreg1 = (heth->Instance)->MACFCR;
1626
    /* Clear xx bits */
1627
    tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
1628
 
1629
    tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) |
1630
                          macconf->ZeroQuantaPause |
1631
                          macconf->PauseLowThreshold |
1632
                          macconf->UnicastPauseFrameDetect |
1633
                          macconf->ReceiveFlowControl |
1634
                          macconf->TransmitFlowControl);
1635
 
1636
    /* Write to ETHERNET MACFCR */
1637
    (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
1638
 
1639
    /* Wait until the write operation will be taken into account :
1640
    at least four TX_CLK/RX_CLK clock cycles */
1641
    tmpreg1 = (heth->Instance)->MACFCR;
1642
    HAL_Delay(ETH_REG_WRITE_DELAY);
1643
    (heth->Instance)->MACFCR = tmpreg1;
1644
 
1645
    /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
1646
    (heth->Instance)->MACVLANTR = (uint32_t)(macconf->VLANTagComparison |
1647
                                             macconf->VLANTagIdentifier);
1648
 
1649
    /* Wait until the write operation will be taken into account :
1650
    at least four TX_CLK/RX_CLK clock cycles */
1651
    tmpreg1 = (heth->Instance)->MACVLANTR;
1652
    HAL_Delay(ETH_REG_WRITE_DELAY);
1653
    (heth->Instance)->MACVLANTR = tmpreg1;
1654
  }
1655
  else /* macconf == NULL : here we just configure Speed and Duplex mode */
1656
  {
1657
    /*------------------------ ETHERNET MACCR Configuration --------------------*/
1658
    /* Get the ETHERNET MACCR value */
1659
    tmpreg1 = (heth->Instance)->MACCR;
1660
 
1661
    /* Clear FES and DM bits */
1662
    tmpreg1 &= ~(0x00004800U);
1663
 
1664
    tmpreg1 |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
1665
 
1666
    /* Write to ETHERNET MACCR */
1667
    (heth->Instance)->MACCR = (uint32_t)tmpreg1;
1668
 
1669
    /* Wait until the write operation will be taken into account:
1670
    at least four TX_CLK/RX_CLK clock cycles */
1671
    tmpreg1 = (heth->Instance)->MACCR;
1672
    HAL_Delay(ETH_REG_WRITE_DELAY);
1673
    (heth->Instance)->MACCR = tmpreg1;
1674
  }
1675
 
1676
  /* Set the ETH state to Ready */
1677
  heth->State = HAL_ETH_STATE_READY;
1678
 
1679
  /* Process Unlocked */
1680
  __HAL_UNLOCK(heth);
1681
 
1682
  /* Return function status */
1683
  return HAL_OK;
1684
}
1685
 
1686
/**
1687
  * @brief  Sets ETH DMA Configuration.
1688
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1689
  *         the configuration information for ETHERNET module
1690
  * @param  dmaconf: DMA Configuration structure
1691
  * @retval HAL status
1692
  */
1693
HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
1694
{
1695
  uint32_t tmpreg1 = 0U;
1696
 
1697
  /* Process Locked */
1698
  __HAL_LOCK(heth);
1699
 
1700
  /* Set the ETH peripheral state to BUSY */
1701
  heth->State = HAL_ETH_STATE_BUSY;
1702
 
1703
  /* Check parameters */
1704
  assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame));
1705
  assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward));
1706
  assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame));
1707
  assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward));
1708
  assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl));
1709
  assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames));
1710
  assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames));
1711
  assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl));
1712
  assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate));
1713
  assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats));
1714
  assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst));
1715
  assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength));
1716
  assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength));
1717
  assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength));
1718
  assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration));
1719
 
1720
  /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
1721
  /* Get the ETHERNET DMAOMR value */
1722
  tmpreg1 = (heth->Instance)->DMAOMR;
1723
  /* Clear xx bits */
1724
  tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
1725
 
1726
  tmpreg1 |= (uint32_t)(dmaconf->DropTCPIPChecksumErrorFrame |
1727
                        dmaconf->ReceiveStoreForward |
1728
                        dmaconf->FlushReceivedFrame |
1729
                        dmaconf->TransmitStoreForward |
1730
                        dmaconf->TransmitThresholdControl |
1731
                        dmaconf->ForwardErrorFrames |
1732
                        dmaconf->ForwardUndersizedGoodFrames |
1733
                        dmaconf->ReceiveThresholdControl |
1734
                        dmaconf->SecondFrameOperate);
1735
 
1736
  /* Write to ETHERNET DMAOMR */
1737
  (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
1738
 
1739
  /* Wait until the write operation will be taken into account:
1740
  at least four TX_CLK/RX_CLK clock cycles */
1741
  tmpreg1 = (heth->Instance)->DMAOMR;
1742
  HAL_Delay(ETH_REG_WRITE_DELAY);
1743
  (heth->Instance)->DMAOMR = tmpreg1;
1744
 
1745
  /*----------------------- ETHERNET DMABMR Configuration --------------------*/
1746
  (heth->Instance)->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats |
1747
                                        dmaconf->FixedBurst |
1748
                                        dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
1749
                                        dmaconf->TxDMABurstLength |
1750
                                        (dmaconf->DescriptorSkipLength << 2U) |
1751
                                        dmaconf->DMAArbitration |
1752
                                        ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
1753
 
1754
  /* Wait until the write operation will be taken into account:
1755
     at least four TX_CLK/RX_CLK clock cycles */
1756
  tmpreg1 = (heth->Instance)->DMABMR;
1757
  HAL_Delay(ETH_REG_WRITE_DELAY);
1758
  (heth->Instance)->DMABMR = tmpreg1;
1759
 
1760
  /* Set the ETH state to Ready */
1761
  heth->State = HAL_ETH_STATE_READY;
1762
 
1763
  /* Process Unlocked */
1764
  __HAL_UNLOCK(heth);
1765
 
1766
  /* Return function status */
1767
  return HAL_OK;
1768
}
1769
 
1770
/**
1771
  * @}
1772
  */
1773
 
1774
/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions
1775
  *  @brief   Peripheral State functions
1776
  *
1777
  @verbatim
1778
  ===============================================================================
1779
                         ##### Peripheral State functions #####
1780
  ===============================================================================
1781
  [..]
1782
  This subsection permits to get in run-time the status of the peripheral
1783
  and the data flow.
1784
       (+) Get the ETH handle state:
1785
           HAL_ETH_GetState();
1786
 
1787
 
1788
  @endverbatim
1789
  * @{
1790
  */
1791
 
1792
/**
1793
  * @brief  Return the ETH HAL state
1794
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1795
  *         the configuration information for ETHERNET module
1796
  * @retval HAL state
1797
  */
1798
HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
1799
{
1800
  /* Return ETH state */
1801
  return heth->State;
1802
}
1803
 
1804
/**
1805
  * @}
1806
  */
1807
 
1808
/**
1809
  * @}
1810
  */
1811
 
1812
/** @addtogroup ETH_Private_Functions
1813
  * @{
1814
  */
1815
 
1816
/**
1817
  * @brief  Configures Ethernet MAC and DMA with default parameters.
1818
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1819
  *         the configuration information for ETHERNET module
1820
  * @param  err: Ethernet Init error
1821
  * @retval HAL status
1822
  */
1823
static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
1824
{
1825
  ETH_MACInitTypeDef macinit;
1826
  ETH_DMAInitTypeDef dmainit;
1827
  uint32_t tmpreg1 = 0U;
1828
 
1829
  if (err != ETH_SUCCESS) /* Auto-negotiation failed */
1830
  {
1831
    /* Set Ethernet duplex mode to Full-duplex */
1832
    (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
1833
 
1834
    /* Set Ethernet speed to 100M */
1835
    (heth->Init).Speed = ETH_SPEED_100M;
1836
  }
1837
 
1838
  /* Ethernet MAC default initialization **************************************/
1839
  macinit.Watchdog = ETH_WATCHDOG_ENABLE;
1840
  macinit.Jabber = ETH_JABBER_ENABLE;
1841
  macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
1842
  macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
1843
  macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
1844
  macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
1845
  if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
1846
  {
1847
    macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
1848
  }
1849
  else
1850
  {
1851
    macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
1852
  }
1853
  macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
1854
  macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
1855
  macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
1856
  macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
1857
  macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
1858
  macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
1859
  macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
1860
  macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
1861
  macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
1862
  macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
1863
  macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
1864
  macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
1865
  macinit.HashTableHigh = 0x0U;
1866
  macinit.HashTableLow = 0x0U;
1867
  macinit.PauseTime = 0x0U;
1868
  macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
1869
  macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
1870
  macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
1871
  macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
1872
  macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
1873
  macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
1874
  macinit.VLANTagIdentifier = 0x0U;
1875
 
1876
  /*------------------------ ETHERNET MACCR Configuration --------------------*/
1877
  /* Get the ETHERNET MACCR value */
1878
  tmpreg1 = (heth->Instance)->MACCR;
1879
  /* Clear WD, PCE, PS, TE and RE bits */
1880
  tmpreg1 &= ETH_MACCR_CLEAR_MASK;
1881
  /* Set the WD bit according to ETH Watchdog value */
1882
  /* Set the JD: bit according to ETH Jabber value */
1883
  /* Set the IFG bit according to ETH InterFrameGap value */
1884
  /* Set the DCRS bit according to ETH CarrierSense value */
1885
  /* Set the FES bit according to ETH Speed value */
1886
  /* Set the DO bit according to ETH ReceiveOwn value */
1887
  /* Set the LM bit according to ETH LoopbackMode value */
1888
  /* Set the DM bit according to ETH Mode value */
1889
  /* Set the IPCO bit according to ETH ChecksumOffload value */
1890
  /* Set the DR bit according to ETH RetryTransmission value */
1891
  /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
1892
  /* Set the BL bit according to ETH BackOffLimit value */
1893
  /* Set the DC bit according to ETH DeferralCheck value */
1894
  tmpreg1 |= (uint32_t)(macinit.Watchdog |
1895
                        macinit.Jabber |
1896
                        macinit.InterFrameGap |
1897
                        macinit.CarrierSense |
1898
                        (heth->Init).Speed |
1899
                        macinit.ReceiveOwn |
1900
                        macinit.LoopbackMode |
1901
                        (heth->Init).DuplexMode |
1902
                        macinit.ChecksumOffload |
1903
                        macinit.RetryTransmission |
1904
                        macinit.AutomaticPadCRCStrip |
1905
                        macinit.BackOffLimit |
1906
                        macinit.DeferralCheck);
1907
 
1908
  /* Write to ETHERNET MACCR */
1909
  (heth->Instance)->MACCR = (uint32_t)tmpreg1;
1910
 
1911
  /* Wait until the write operation will be taken into account:
1912
     at least four TX_CLK/RX_CLK clock cycles */
1913
  tmpreg1 = (heth->Instance)->MACCR;
1914
  HAL_Delay(ETH_REG_WRITE_DELAY);
1915
  (heth->Instance)->MACCR = tmpreg1;
1916
 
1917
  /*----------------------- ETHERNET MACFFR Configuration --------------------*/
1918
  /* Set the RA bit according to ETH ReceiveAll value */
1919
  /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
1920
  /* Set the PCF bit according to ETH PassControlFrames value */
1921
  /* Set the DBF bit according to ETH BroadcastFramesReception value */
1922
  /* Set the DAIF bit according to ETH DestinationAddrFilter value */
1923
  /* Set the PR bit according to ETH PromiscuousMode value */
1924
  /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
1925
  /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
1926
  /* Write to ETHERNET MACFFR */
1927
  (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
1928
                                        macinit.SourceAddrFilter |
1929
                                        macinit.PassControlFrames |
1930
                                        macinit.BroadcastFramesReception |
1931
                                        macinit.DestinationAddrFilter |
1932
                                        macinit.PromiscuousMode |
1933
                                        macinit.MulticastFramesFilter |
1934
                                        macinit.UnicastFramesFilter);
1935
 
1936
  /* Wait until the write operation will be taken into account:
1937
     at least four TX_CLK/RX_CLK clock cycles */
1938
  tmpreg1 = (heth->Instance)->MACFFR;
1939
  HAL_Delay(ETH_REG_WRITE_DELAY);
1940
  (heth->Instance)->MACFFR = tmpreg1;
1941
 
1942
  /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
1943
  /* Write to ETHERNET MACHTHR */
1944
  (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
1945
 
1946
  /* Write to ETHERNET MACHTLR */
1947
  (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;
1948
  /*----------------------- ETHERNET MACFCR Configuration -------------------*/
1949
 
1950
  /* Get the ETHERNET MACFCR value */
1951
  tmpreg1 = (heth->Instance)->MACFCR;
1952
  /* Clear xx bits */
1953
  tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
1954
 
1955
  /* Set the PT bit according to ETH PauseTime value */
1956
  /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
1957
  /* Set the PLT bit according to ETH PauseLowThreshold value */
1958
  /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
1959
  /* Set the RFE bit according to ETH ReceiveFlowControl value */
1960
  /* Set the TFE bit according to ETH TransmitFlowControl value */
1961
  tmpreg1 |= (uint32_t)((macinit.PauseTime << 16U) |
1962
                        macinit.ZeroQuantaPause |
1963
                        macinit.PauseLowThreshold |
1964
                        macinit.UnicastPauseFrameDetect |
1965
                        macinit.ReceiveFlowControl |
1966
                        macinit.TransmitFlowControl);
1967
 
1968
  /* Write to ETHERNET MACFCR */
1969
  (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
1970
 
1971
  /* Wait until the write operation will be taken into account:
1972
  at least four TX_CLK/RX_CLK clock cycles */
1973
  tmpreg1 = (heth->Instance)->MACFCR;
1974
  HAL_Delay(ETH_REG_WRITE_DELAY);
1975
  (heth->Instance)->MACFCR = tmpreg1;
1976
 
1977
  /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
1978
  /* Set the ETV bit according to ETH VLANTagComparison value */
1979
  /* Set the VL bit according to ETH VLANTagIdentifier value */
1980
  (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
1981
                                           macinit.VLANTagIdentifier);
1982
 
1983
  /* Wait until the write operation will be taken into account:
1984
     at least four TX_CLK/RX_CLK clock cycles */
1985
  tmpreg1 = (heth->Instance)->MACVLANTR;
1986
  HAL_Delay(ETH_REG_WRITE_DELAY);
1987
  (heth->Instance)->MACVLANTR = tmpreg1;
1988
 
1989
  /* Ethernet DMA default initialization ************************************/
1990
  dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
1991
  dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
1992
  dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
1993
  dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
1994
  dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
1995
  dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
1996
  dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
1997
  dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
1998
  dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
1999
  dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
2000
  dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
2001
  dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2002
  dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2003
  dmainit.DescriptorSkipLength = 0x0U;
2004
  dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
2005
 
2006
  /* Get the ETHERNET DMAOMR value */
2007
  tmpreg1 = (heth->Instance)->DMAOMR;
2008
  /* Clear xx bits */
2009
  tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
2010
 
2011
  /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
2012
  /* Set the RSF bit according to ETH ReceiveStoreForward value */
2013
  /* Set the DFF bit according to ETH FlushReceivedFrame value */
2014
  /* Set the TSF bit according to ETH TransmitStoreForward value */
2015
  /* Set the TTC bit according to ETH TransmitThresholdControl value */
2016
  /* Set the FEF bit according to ETH ForwardErrorFrames value */
2017
  /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
2018
  /* Set the RTC bit according to ETH ReceiveThresholdControl value */
2019
  /* Set the OSF bit according to ETH SecondFrameOperate value */
2020
  tmpreg1 |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
2021
                        dmainit.ReceiveStoreForward |
2022
                        dmainit.FlushReceivedFrame |
2023
                        dmainit.TransmitStoreForward |
2024
                        dmainit.TransmitThresholdControl |
2025
                        dmainit.ForwardErrorFrames |
2026
                        dmainit.ForwardUndersizedGoodFrames |
2027
                        dmainit.ReceiveThresholdControl |
2028
                        dmainit.SecondFrameOperate);
2029
 
2030
  /* Write to ETHERNET DMAOMR */
2031
  (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
2032
 
2033
  /* Wait until the write operation will be taken into account:
2034
     at least four TX_CLK/RX_CLK clock cycles */
2035
  tmpreg1 = (heth->Instance)->DMAOMR;
2036
  HAL_Delay(ETH_REG_WRITE_DELAY);
2037
  (heth->Instance)->DMAOMR = tmpreg1;
2038
 
2039
  /*----------------------- ETHERNET DMABMR Configuration ------------------*/
2040
  /* Set the AAL bit according to ETH AddressAlignedBeats value */
2041
  /* Set the FB bit according to ETH FixedBurst value */
2042
  /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
2043
  /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
2044
  /* Set the DSL bit according to ETH DesciptorSkipLength value */
2045
  /* Set the PR and DA bits according to ETH DMAArbitration value */
2046
  (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
2047
                                        dmainit.FixedBurst |
2048
                                        dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
2049
                                        dmainit.TxDMABurstLength |
2050
                                        (dmainit.DescriptorSkipLength << 2U) |
2051
                                        dmainit.DMAArbitration |
2052
                                        ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
2053
 
2054
  /* Wait until the write operation will be taken into account:
2055
     at least four TX_CLK/RX_CLK clock cycles */
2056
  tmpreg1 = (heth->Instance)->DMABMR;
2057
  HAL_Delay(ETH_REG_WRITE_DELAY);
2058
  (heth->Instance)->DMABMR = tmpreg1;
2059
 
2060
  if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
2061
  {
2062
    /* Enable the Ethernet Rx Interrupt */
2063
    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
2064
  }
2065
 
2066
  /* Initialize MAC address in ethernet MAC */
2067
  ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
2068
}
2069
 
2070
/**
2071
  * @brief  Configures the selected MAC address.
2072
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2073
  *         the configuration information for ETHERNET module
2074
  * @param  MacAddr: The MAC address to configure
2075
  *          This parameter can be one of the following values:
2076
  *             @arg ETH_MAC_Address0: MAC Address0
2077
  *             @arg ETH_MAC_Address1: MAC Address1
2078
  *             @arg ETH_MAC_Address2: MAC Address2
2079
  *             @arg ETH_MAC_Address3: MAC Address3
2080
  * @param  Addr: Pointer to MAC address buffer data (6 bytes)
2081
  * @retval HAL status
2082
  */
2083
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
2084
{
2085
  uint32_t tmpreg1;
2086
 
2087
  /* Prevent unused argument(s) compilation warning */
2088
  UNUSED(heth);
2089
 
2090
  /* Check the parameters */
2091
  assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
2092
 
2093
  /* Calculate the selected MAC address high register */
2094
  tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U];
2095
  /* Load the selected MAC address high register */
2096
  (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1;
2097
  /* Calculate the selected MAC address low register */
2098
  tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U];
2099
 
2100
  /* Load the selected MAC address low register */
2101
  (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1;
2102
}
2103
 
2104
/**
2105
  * @brief  Enables the MAC transmission.
2106
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2107
  *         the configuration information for ETHERNET module
2108
  * @retval None
2109
  */
2110
static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth)
2111
{
2112
  __IO uint32_t tmpreg1 = 0U;
2113
 
2114
  /* Enable the MAC transmission */
2115
  (heth->Instance)->MACCR |= ETH_MACCR_TE;
2116
 
2117
  /* Wait until the write operation will be taken into account:
2118
     at least four TX_CLK/RX_CLK clock cycles */
2119
  tmpreg1 = (heth->Instance)->MACCR;
2120
  ETH_Delay(ETH_REG_WRITE_DELAY);
2121
  (heth->Instance)->MACCR = tmpreg1;
2122
}
2123
 
2124
/**
2125
  * @brief  Disables the MAC transmission.
2126
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2127
  *         the configuration information for ETHERNET module
2128
  * @retval None
2129
  */
2130
static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth)
2131
{
2132
  __IO uint32_t tmpreg1 = 0U;
2133
 
2134
  /* Disable the MAC transmission */
2135
  (heth->Instance)->MACCR &= ~ETH_MACCR_TE;
2136
 
2137
  /* Wait until the write operation will be taken into account:
2138
     at least four TX_CLK/RX_CLK clock cycles */
2139
  tmpreg1 = (heth->Instance)->MACCR;
2140
  ETH_Delay(ETH_REG_WRITE_DELAY);
2141
  (heth->Instance)->MACCR = tmpreg1;
2142
}
2143
 
2144
/**
2145
  * @brief  Enables the MAC reception.
2146
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2147
  *         the configuration information for ETHERNET module
2148
  * @retval None
2149
  */
2150
static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth)
2151
{
2152
  __IO uint32_t tmpreg1 = 0U;
2153
 
2154
  /* Enable the MAC reception */
2155
  (heth->Instance)->MACCR |= ETH_MACCR_RE;
2156
 
2157
  /* Wait until the write operation will be taken into account:
2158
     at least four TX_CLK/RX_CLK clock cycles */
2159
  tmpreg1 = (heth->Instance)->MACCR;
2160
  ETH_Delay(ETH_REG_WRITE_DELAY);
2161
  (heth->Instance)->MACCR = tmpreg1;
2162
}
2163
 
2164
/**
2165
  * @brief  Disables the MAC reception.
2166
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2167
  *         the configuration information for ETHERNET module
2168
  * @retval None
2169
  */
2170
static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth)
2171
{
2172
  __IO uint32_t tmpreg1 = 0U;
2173
 
2174
  /* Disable the MAC reception */
2175
  (heth->Instance)->MACCR &= ~ETH_MACCR_RE;
2176
 
2177
  /* Wait until the write operation will be taken into account:
2178
     at least four TX_CLK/RX_CLK clock cycles */
2179
  tmpreg1 = (heth->Instance)->MACCR;
2180
  ETH_Delay(ETH_REG_WRITE_DELAY);
2181
  (heth->Instance)->MACCR = tmpreg1;
2182
}
2183
 
2184
/**
2185
  * @brief  Enables the DMA transmission.
2186
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2187
  *         the configuration information for ETHERNET module
2188
  * @retval None
2189
  */
2190
static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth)
2191
{
2192
  /* Enable the DMA transmission */
2193
  (heth->Instance)->DMAOMR |= ETH_DMAOMR_ST;
2194
}
2195
 
2196
/**
2197
  * @brief  Disables the DMA transmission.
2198
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2199
  *         the configuration information for ETHERNET module
2200
  * @retval None
2201
  */
2202
static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth)
2203
{
2204
  /* Disable the DMA transmission */
2205
  (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_ST;
2206
}
2207
 
2208
/**
2209
  * @brief  Enables the DMA reception.
2210
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2211
  *         the configuration information for ETHERNET module
2212
  * @retval None
2213
  */
2214
static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth)
2215
{
2216
  /* Enable the DMA reception */
2217
  (heth->Instance)->DMAOMR |= ETH_DMAOMR_SR;
2218
}
2219
 
2220
/**
2221
  * @brief  Disables the DMA reception.
2222
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2223
  *         the configuration information for ETHERNET module
2224
  * @retval None
2225
  */
2226
static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth)
2227
{
2228
  /* Disable the DMA reception */
2229
  (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_SR;
2230
}
2231
 
2232
/**
2233
  * @brief  Clears the ETHERNET transmit FIFO.
2234
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2235
  *         the configuration information for ETHERNET module
2236
  * @retval None
2237
  */
2238
static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
2239
{
2240
  __IO uint32_t tmpreg1 = 0U;
2241
 
2242
  /* Set the Flush Transmit FIFO bit */
2243
  (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;
2244
 
2245
  /* Wait until the write operation will be taken into account:
2246
     at least four TX_CLK/RX_CLK clock cycles */
2247
  tmpreg1 = (heth->Instance)->DMAOMR;
2248
  ETH_Delay(ETH_REG_WRITE_DELAY);
2249
  (heth->Instance)->DMAOMR = tmpreg1;
2250
}
2251
 
2252
/**
2253
  * @brief  This function provides delay (in milliseconds) based on CPU cycles method.
2254
  * @param  mdelay: specifies the delay time length, in milliseconds.
2255
  * @retval None
2256
  */
2257
static void ETH_Delay(uint32_t mdelay)
2258
{
2259
  __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
2260
  do
2261
  {
2262
    __NOP();
2263
  }
2264
  while (Delay --);
2265
}
2266
 
2267
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2268
static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
2269
{
2270
  /* Init the ETH Callback settings */
2271
  heth->TxCpltCallback       = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback   */
2272
  heth->RxCpltCallback       = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback   */
2273
  heth->DMAErrorCallback     = HAL_ETH_ErrorCallback;  /* Legacy weak DMAErrorCallback */
2274
}
2275
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2276
 
2277
/**
2278
  * @}
2279
  */
2280
 
2281
#endif /* ETH */
2282
 
2283
#endif /* HAL_ETH_MODULE_ENABLED */
2284
/**
2285
  * @}
2286
  */
2287
 
2288
/**
2289
  * @}
2290
  */
2291
 
2292
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/