Subversion Repositories LedShow

Rev

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