STM32F103xB HAL User Manual
stm32f1xx_hal_eth.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f1xx_hal_eth.c
00004   * @author  MCD Application Team
00005   * @brief   ETH HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Ethernet (ETH) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + IO operation functions
00010   *           + Peripheral Control functions
00011   *           + Peripheral State and Errors functions
00012   *
00013   @verbatim
00014   ==============================================================================
00015                     ##### How to use this driver #####
00016   ==============================================================================
00017     [..]
00018       (#)Declare a ETH_HandleTypeDef handle structure, for example:
00019          ETH_HandleTypeDef  heth;
00020 
00021       (#)Fill parameters of Init structure in heth handle
00022 
00023       (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
00024 
00025       (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
00026           (##) Enable the Ethernet interface clock using
00027                (+++) __HAL_RCC_ETHMAC_CLK_ENABLE();
00028                (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE();
00029                (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE();
00030 
00031           (##) Initialize the related GPIO clocks
00032           (##) Configure Ethernet pin-out
00033           (##) Configure Ethernet NVIC interrupt (IT mode)
00034 
00035       (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:
00036           (##) HAL_ETH_DMATxDescListInit(); for Transmission process
00037           (##) HAL_ETH_DMARxDescListInit(); for Reception process
00038 
00039       (#)Enable MAC and DMA transmission and reception:
00040           (##) HAL_ETH_Start();
00041 
00042       (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer
00043          the frame to MAC TX FIFO:
00044          (##) HAL_ETH_TransmitFrame();
00045 
00046       (#)Poll for a received frame in ETH RX DMA Descriptors and get received
00047          frame parameters
00048          (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)
00049 
00050       (#) Get a received frame when an ETH RX interrupt occurs:
00051          (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)
00052 
00053       (#) Communicate with external PHY device:
00054          (##) Read a specific register from the PHY
00055               HAL_ETH_ReadPHYRegister();
00056          (##) Write data to a specific RHY register:
00057               HAL_ETH_WritePHYRegister();
00058 
00059       (#) Configure the Ethernet MAC after ETH peripheral initialization
00060           HAL_ETH_ConfigMAC(); all MAC parameters should be filled.
00061 
00062       (#) Configure the Ethernet DMA after ETH peripheral initialization
00063           HAL_ETH_ConfigDMA(); all DMA parameters should be filled.
00064 
00065       -@- The PTP protocol and the DMA descriptors ring mode are not supported
00066           in this driver
00067 *** Callback registration ***
00068   =============================================
00069 
00070   The compilation define  USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
00071   allows the user to configure dynamically the driver callbacks.
00072   Use Function @ref HAL_ETH_RegisterCallback() to register an interrupt callback.
00073 
00074   Function @ref HAL_ETH_RegisterCallback() allows to register following callbacks:
00075     (+) TxCpltCallback   : Tx Complete Callback.
00076     (+) RxCpltCallback   : Rx Complete Callback.
00077     (+) DMAErrorCallback : DMA Error Callback.
00078     (+) MspInitCallback  : MspInit Callback.
00079     (+) MspDeInitCallback: MspDeInit Callback.
00080 
00081   This function takes as parameters the HAL peripheral handle, the Callback ID
00082   and a pointer to the user callback function.
00083 
00084   Use function @ref HAL_ETH_UnRegisterCallback() to reset a callback to the default
00085   weak function.
00086   @ref HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
00087   and the Callback ID.
00088   This function allows to reset following callbacks:
00089     (+) TxCpltCallback   : Tx Complete Callback.
00090     (+) RxCpltCallback   : Rx Complete Callback.
00091     (+) DMAErrorCallback : DMA Error Callback.
00092     (+) MspInitCallback  : MspInit Callback.
00093     (+) MspDeInitCallback: MspDeInit Callback.
00094 
00095   By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
00096   all callbacks are set to the corresponding weak functions:
00097   examples @ref HAL_ETH_TxCpltCallback(), @ref HAL_ETH_RxCpltCallback().
00098   Exception done for MspInit and MspDeInit functions that are
00099   reset to the legacy weak function in the HAL_ETH_Init/ @ref HAL_ETH_DeInit only when
00100   these callbacks are null (not registered beforehand).
00101   if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ @ref HAL_ETH_DeInit
00102   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
00103 
00104   Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
00105   Exception done MspInit/MspDeInit that can be registered/unregistered
00106   in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
00107   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00108   In that case first register the MspInit/MspDeInit user callbacks
00109   using @ref HAL_ETH_RegisterCallback() before calling @ref HAL_ETH_DeInit
00110   or HAL_ETH_Init function.
00111 
00112   When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
00113   not defined, the callback registration feature is not available and all callbacks
00114   are set to the corresponding weak functions.
00115 
00116   @endverbatim
00117   ******************************************************************************
00118   * @attention
00119   *
00120   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
00121   * All rights reserved.</center></h2>
00122   *
00123   * This software component is licensed by ST under BSD 3-Clause license,
00124   * the "License"; You may not use this file except in compliance with the
00125   * License. You may obtain a copy of the License at:
00126   *                        opensource.org/licenses/BSD-3-Clause
00127   *
00128   ******************************************************************************
00129   */
00130 
00131 /* Includes ------------------------------------------------------------------*/
00132 #include "stm32f1xx_hal.h"
00133 
00134 /** @addtogroup STM32F1xx_HAL_Driver
00135   * @{
00136   */
00137 
00138 /** @defgroup ETH ETH
00139   * @brief ETH HAL module driver
00140   * @{
00141   */
00142 
00143 #ifdef HAL_ETH_MODULE_ENABLED
00144 
00145 #if defined (ETH)
00146 
00147 /* Private typedef -----------------------------------------------------------*/
00148 /* Private define ------------------------------------------------------------*/
00149 /** @defgroup ETH_Private_Constants ETH Private Constants
00150   * @{
00151   */
00152 #define ETH_TIMEOUT_SWRESET               500U
00153 #define ETH_TIMEOUT_LINKED_STATE          5000U
00154 #define ETH_TIMEOUT_AUTONEGO_COMPLETED    5000U
00155 
00156 /**
00157   * @}
00158   */
00159 /* Private macro -------------------------------------------------------------*/
00160 /* Private variables ---------------------------------------------------------*/
00161 /* Private function prototypes -----------------------------------------------*/
00162 /** @defgroup ETH_Private_Functions ETH Private Functions
00163   * @{
00164   */
00165 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err);
00166 static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
00167 static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth);
00168 static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth);
00169 static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth);
00170 static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth);
00171 static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth);
00172 static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth);
00173 static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth);
00174 static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth);
00175 static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
00176 static void ETH_Delay(uint32_t mdelay);
00177 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
00178 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
00179 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
00180 
00181 /**
00182   * @}
00183   */
00184 /* Private functions ---------------------------------------------------------*/
00185 
00186 /** @defgroup ETH_Exported_Functions ETH Exported Functions
00187   * @{
00188   */
00189 
00190 /** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions
00191   *  @brief   Initialization and Configuration functions
00192   *
00193   @verbatim
00194   ===============================================================================
00195             ##### Initialization and de-initialization functions #####
00196   ===============================================================================
00197   [..]  This section provides functions allowing to:
00198       (+) Initialize and configure the Ethernet peripheral
00199       (+) De-initialize the Ethernet peripheral
00200 
00201   @endverbatim
00202   * @{
00203   */
00204 
00205 /**
00206   * @brief  Initializes the Ethernet MAC and DMA according to default
00207   *         parameters.
00208   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
00209   *         the configuration information for ETHERNET module
00210   * @retval HAL status
00211   */
00212 HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
00213 {
00214   uint32_t tmpreg1 = 0U, phyreg = 0U;
00215   uint32_t hclk = 60000000U;
00216   uint32_t tickstart = 0U;
00217   uint32_t err = ETH_SUCCESS;
00218 
00219   /* Check the ETH peripheral state */
00220   if (heth == NULL)
00221   {
00222     return HAL_ERROR;
00223   }
00224 
00225   /* Check parameters */
00226   assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
00227   assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
00228   assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
00229   assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
00230 
00231   if (heth->State == HAL_ETH_STATE_RESET)
00232   {
00233     /* Allocate lock resource and initialize it */
00234     heth->Lock = HAL_UNLOCKED;
00235 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
00236     ETH_InitCallbacksToDefault(heth);
00237 
00238     if (heth->MspInitCallback == NULL)
00239     {
00240       /* Init the low level hardware : GPIO, CLOCK, NVIC. */
00241       heth->MspInitCallback = HAL_ETH_MspInit;
00242     }
00243     heth->MspInitCallback(heth);
00244 
00245 #else
00246     /* Init the low level hardware : GPIO, CLOCK, NVIC. */
00247     HAL_ETH_MspInit(heth);
00248 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
00249   }
00250 
00251   /* Select MII or RMII Mode*/
00252   AFIO->MAPR &= ~(AFIO_MAPR_MII_RMII_SEL);
00253   AFIO->MAPR |= (uint32_t)heth->Init.MediaInterface;
00254 
00255   /* Ethernet Software reset */
00256   /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
00257   /* After reset all the registers holds their respective reset values */
00258   (heth->Instance)->DMABMR |= ETH_DMABMR_SR;
00259 
00260   /* Get tick */
00261   tickstart = HAL_GetTick();
00262 
00263   /* Wait for software reset */
00264   while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
00265   {
00266     /* Check for the Timeout */
00267     if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_SWRESET)
00268     {
00269       heth->State = HAL_ETH_STATE_TIMEOUT;
00270 
00271       /* Process Unlocked */
00272       __HAL_UNLOCK(heth);
00273 
00274       /* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are
00275          not available, please check your external PHY or the IO configuration */
00276       return HAL_TIMEOUT;
00277     }
00278   }
00279 
00280   /*-------------------------------- MAC Initialization ----------------------*/
00281   /* Get the ETHERNET MACMIIAR value */
00282   tmpreg1 = (heth->Instance)->MACMIIAR;
00283   /* Clear CSR Clock Range CR[2:0] bits */
00284   tmpreg1 &= ETH_MACMIIAR_CR_MASK;
00285 
00286   /* Get hclk frequency value */
00287   hclk = HAL_RCC_GetHCLKFreq();
00288 
00289   /* Set CR bits depending on hclk value */
00290   if ((hclk >= 20000000U) && (hclk < 35000000U))
00291   {
00292     /* CSR Clock Range between 20-35 MHz */
00293     tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV16;
00294   }
00295   else if ((hclk >= 35000000U) && (hclk < 60000000U))
00296   {
00297     /* CSR Clock Range between 35-60 MHz */
00298     tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV26;
00299   }
00300   else
00301   {
00302     /* CSR Clock Range between 60-72 MHz */
00303     tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV42;
00304   }
00305 
00306   /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
00307   (heth->Instance)->MACMIIAR = (uint32_t)tmpreg1;
00308 
00309   /*-------------------- PHY initialization and configuration ----------------*/
00310   /* Put the PHY in reset mode */
00311   if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK)
00312   {
00313     /* In case of write timeout */
00314     err = ETH_ERROR;
00315 
00316     /* Config MAC and DMA */
00317     ETH_MACDMAConfig(heth, err);
00318 
00319     /* Set the ETH peripheral state to READY */
00320     heth->State = HAL_ETH_STATE_READY;
00321 
00322     /* Return HAL_ERROR */
00323     return HAL_ERROR;
00324   }
00325 
00326   /* Delay to assure PHY reset */
00327   HAL_Delay(PHY_RESET_DELAY);
00328 
00329   if ((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
00330   {
00331     /* Get tick */
00332     tickstart = HAL_GetTick();
00333 
00334     /* We wait for linked status */
00335     do
00336     {
00337       HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
00338 
00339       /* Check for the Timeout */
00340       if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_LINKED_STATE)
00341       {
00342         /* In case of write timeout */
00343         err = ETH_ERROR;
00344 
00345         /* Config MAC and DMA */
00346         ETH_MACDMAConfig(heth, err);
00347 
00348         heth->State = HAL_ETH_STATE_READY;
00349 
00350         /* Process Unlocked */
00351         __HAL_UNLOCK(heth);
00352 
00353         return HAL_TIMEOUT;
00354       }
00355     }
00356     while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));
00357 
00358 
00359     /* Enable Auto-Negotiation */
00360     if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK)
00361     {
00362       /* In case of write timeout */
00363       err = ETH_ERROR;
00364 
00365       /* Config MAC and DMA */
00366       ETH_MACDMAConfig(heth, err);
00367 
00368       /* Set the ETH peripheral state to READY */
00369       heth->State = HAL_ETH_STATE_READY;
00370 
00371       /* Return HAL_ERROR */
00372       return HAL_ERROR;
00373     }
00374 
00375     /* Get tick */
00376     tickstart = HAL_GetTick();
00377 
00378     /* Wait until the auto-negotiation will be completed */
00379     do
00380     {
00381       HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
00382 
00383       /* Check for the Timeout */
00384       if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_AUTONEGO_COMPLETED)
00385       {
00386         /* In case of write timeout */
00387         err = ETH_ERROR;
00388 
00389         /* Config MAC and DMA */
00390         ETH_MACDMAConfig(heth, err);
00391 
00392         heth->State = HAL_ETH_STATE_READY;
00393 
00394         /* Process Unlocked */
00395         __HAL_UNLOCK(heth);
00396 
00397         return HAL_TIMEOUT;
00398       }
00399 
00400     }
00401     while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
00402 
00403     /* Read the result of the auto-negotiation */
00404     if ((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK)
00405     {
00406       /* In case of write timeout */
00407       err = ETH_ERROR;
00408 
00409       /* Config MAC and DMA */
00410       ETH_MACDMAConfig(heth, err);
00411 
00412       /* Set the ETH peripheral state to READY */
00413       heth->State = HAL_ETH_STATE_READY;
00414 
00415       /* Return HAL_ERROR */
00416       return HAL_ERROR;
00417     }
00418 
00419     /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
00420     if ((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
00421     {
00422       /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
00423       (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
00424     }
00425     else
00426     {
00427       /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
00428       (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
00429     }
00430     /* Configure the MAC with the speed fixed by the auto-negotiation process */
00431     if ((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS)
00432     {
00433       /* Set Ethernet speed to 10M following the auto-negotiation */
00434       (heth->Init).Speed = ETH_SPEED_10M;
00435     }
00436     else
00437     {
00438       /* Set Ethernet speed to 100M following the auto-negotiation */
00439       (heth->Init).Speed = ETH_SPEED_100M;
00440     }
00441   }
00442   else /* AutoNegotiation Disable */
00443   {
00444     /* Check parameters */
00445     assert_param(IS_ETH_SPEED(heth->Init.Speed));
00446     assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
00447 
00448     /* Set MAC Speed and Duplex Mode */
00449     if (HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) |
00450                                                  (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK)
00451     {
00452       /* In case of write timeout */
00453       err = ETH_ERROR;
00454 
00455       /* Config MAC and DMA */
00456       ETH_MACDMAConfig(heth, err);
00457 
00458       /* Set the ETH peripheral state to READY */
00459       heth->State = HAL_ETH_STATE_READY;
00460 
00461       /* Return HAL_ERROR */
00462       return HAL_ERROR;
00463     }
00464 
00465     /* Delay to assure PHY configuration */
00466     HAL_Delay(PHY_CONFIG_DELAY);
00467   }
00468 
00469   /* Config MAC and DMA */
00470   ETH_MACDMAConfig(heth, err);
00471 
00472   /* Set ETH HAL State to Ready */
00473   heth->State = HAL_ETH_STATE_READY;
00474 
00475   /* Return function status */
00476   return HAL_OK;
00477 }
00478 
00479 /**
00480   * @brief  De-Initializes the ETH peripheral.
00481   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
00482   *         the configuration information for ETHERNET module
00483   * @retval HAL status
00484   */
00485 HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
00486 {
00487   /* Set the ETH peripheral state to BUSY */
00488   heth->State = HAL_ETH_STATE_BUSY;
00489 
00490 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
00491   if (heth->MspDeInitCallback == NULL)
00492   {
00493     heth->MspDeInitCallback = HAL_ETH_MspDeInit;
00494   }
00495   /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
00496   heth->MspDeInitCallback(heth);
00497 #else
00498   /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
00499   HAL_ETH_MspDeInit(heth);
00500 #endif
00501 
00502   /* Set ETH HAL state to Disabled */
00503   heth->State = HAL_ETH_STATE_RESET;
00504 
00505   /* Release Lock */
00506   __HAL_UNLOCK(heth);
00507 
00508   /* Return function status */
00509   return HAL_OK;
00510 }
00511 
00512 /**
00513   * @brief  Initializes the DMA Tx descriptors in chain mode.
00514   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
00515   *         the configuration information for ETHERNET module
00516   * @param  DMATxDescTab: Pointer to the first Tx desc list
00517   * @param  TxBuff: Pointer to the first TxBuffer list
00518   * @param  TxBuffCount: Number of the used Tx desc in the list
00519   * @retval HAL status
00520   */
00521 HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount)
00522 {
00523   uint32_t i = 0U;
00524   ETH_DMADescTypeDef *dmatxdesc;
00525 
00526   /* Process Locked */
00527   __HAL_LOCK(heth);
00528 
00529   /* Set the ETH peripheral state to BUSY */
00530   heth->State = HAL_ETH_STATE_BUSY;
00531 
00532   /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */
00533   heth->TxDesc = DMATxDescTab;
00534 
00535   /* Fill each DMATxDesc descriptor with the right values */
00536   for (i = 0U; i < TxBuffCount; i++)
00537   {
00538     /* Get the pointer on the ith member of the Tx Desc list */
00539     dmatxdesc = DMATxDescTab + i;
00540 
00541     /* Set Second Address Chained bit */
00542     dmatxdesc->Status = ETH_DMATXDESC_TCH;
00543 
00544     /* Set Buffer1 address pointer */
00545     dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i * ETH_TX_BUF_SIZE]);
00546 
00547     if ((heth->Init).ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
00548     {
00549       /* Set the DMA Tx descriptors checksum insertion */
00550       dmatxdesc->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
00551     }
00552 
00553     /* Initialize the next descriptor with the Next Descriptor Polling Enable */
00554     if (i < (TxBuffCount - 1U))
00555     {
00556       /* Set next descriptor address register with next descriptor base address */
00557       dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + i + 1U);
00558     }
00559     else
00560     {
00561       /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
00562       dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
00563     }
00564   }
00565 
00566   /* Set Transmit Descriptor List Address Register */
00567   (heth->Instance)->DMATDLAR = (uint32_t) DMATxDescTab;
00568 
00569   /* Set ETH HAL State to Ready */
00570   heth->State = HAL_ETH_STATE_READY;
00571 
00572   /* Process Unlocked */
00573   __HAL_UNLOCK(heth);
00574 
00575   /* Return function status */
00576   return HAL_OK;
00577 }
00578 
00579 /**
00580   * @brief  Initializes the DMA Rx descriptors in chain mode.
00581   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
00582   *         the configuration information for ETHERNET module
00583   * @param  DMARxDescTab: Pointer to the first Rx desc list
00584   * @param  RxBuff: Pointer to the first RxBuffer list
00585   * @param  RxBuffCount: Number of the used Rx desc in the list
00586   * @retval HAL status
00587   */
00588 HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
00589 {
00590   uint32_t i = 0U;
00591   ETH_DMADescTypeDef *DMARxDesc;
00592 
00593   /* Process Locked */
00594   __HAL_LOCK(heth);
00595 
00596   /* Set the ETH peripheral state to BUSY */
00597   heth->State = HAL_ETH_STATE_BUSY;
00598 
00599   /* Set the Ethernet RxDesc pointer with the first one of the DMARxDescTab list */
00600   heth->RxDesc = DMARxDescTab;
00601 
00602   /* Fill each DMARxDesc descriptor with the right values */
00603   for (i = 0U; i < RxBuffCount; i++)
00604   {
00605     /* Get the pointer on the ith member of the Rx Desc list */
00606     DMARxDesc = DMARxDescTab + i;
00607 
00608     /* Set Own bit of the Rx descriptor Status */
00609     DMARxDesc->Status = ETH_DMARXDESC_OWN;
00610 
00611     /* Set Buffer1 size and Second Address Chained bit */
00612     DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
00613 
00614     /* Set Buffer1 address pointer */
00615     DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_RX_BUF_SIZE]);
00616 
00617     if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
00618     {
00619       /* Enable Ethernet DMA Rx Descriptor interrupt */
00620       DMARxDesc->ControlBufferSize &= ~ETH_DMARXDESC_DIC;
00621     }
00622 
00623     /* Initialize the next descriptor with the Next Descriptor Polling Enable */
00624     if (i < (RxBuffCount - 1U))
00625     {
00626       /* Set next descriptor address register with next descriptor base address */
00627       DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1U);
00628     }
00629     else
00630     {
00631       /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
00632       DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
00633     }
00634   }
00635 
00636   /* Set Receive Descriptor List Address Register */
00637   (heth->Instance)->DMARDLAR = (uint32_t) DMARxDescTab;
00638 
00639   /* Set ETH HAL State to Ready */
00640   heth->State = HAL_ETH_STATE_READY;
00641 
00642   /* Process Unlocked */
00643   __HAL_UNLOCK(heth);
00644 
00645   /* Return function status */
00646   return HAL_OK;
00647 }
00648 
00649 /**
00650   * @brief  Initializes the ETH MSP.
00651   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
00652   *         the configuration information for ETHERNET module
00653   * @retval None
00654   */
00655 __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
00656 {
00657   /* Prevent unused argument(s) compilation warning */
00658   UNUSED(heth);
00659   /* NOTE : This function Should not be modified, when the callback is needed,
00660   the HAL_ETH_MspInit could be implemented in the user file
00661   */
00662 }
00663 
00664 /**
00665   * @brief  DeInitializes ETH MSP.
00666   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
00667   *         the configuration information for ETHERNET module
00668   * @retval None
00669   */
00670 __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
00671 {
00672   /* Prevent unused argument(s) compilation warning */
00673   UNUSED(heth);
00674   /* NOTE : This function Should not be modified, when the callback is needed,
00675   the HAL_ETH_MspDeInit could be implemented in the user file
00676   */
00677 }
00678 
00679 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
00680 /**
00681   * @brief  Register a User ETH Callback
00682   *         To be used instead of the weak predefined callback
00683   * @param heth eth handle
00684   * @param CallbackID ID of the callback to be registered
00685   *        This parameter can be one of the following values:
00686   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
00687   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
00688   *          @arg @ref HAL_ETH_DMA_ERROR_CB_ID   DMA Error Callback ID
00689   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
00690   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
00691   * @param pCallback pointer to the Callback function
00692   * @retval status
00693   */
00694 HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, pETH_CallbackTypeDef pCallback)
00695 {
00696   HAL_StatusTypeDef status = HAL_OK;
00697 
00698   if (pCallback == NULL)
00699   {
00700     return HAL_ERROR;
00701   }
00702   /* Process locked */
00703   __HAL_LOCK(heth);
00704 
00705   if (heth->State == HAL_ETH_STATE_READY)
00706   {
00707     switch (CallbackID)
00708     {
00709       case HAL_ETH_TX_COMPLETE_CB_ID :
00710         heth->TxCpltCallback = pCallback;
00711         break;
00712 
00713       case HAL_ETH_RX_COMPLETE_CB_ID :
00714         heth->RxCpltCallback = pCallback;
00715         break;
00716 
00717       case HAL_ETH_DMA_ERROR_CB_ID :
00718         heth->DMAErrorCallback = pCallback;
00719         break;
00720 
00721       case HAL_ETH_MSPINIT_CB_ID :
00722         heth->MspInitCallback = pCallback;
00723         break;
00724 
00725       case HAL_ETH_MSPDEINIT_CB_ID :
00726         heth->MspDeInitCallback = pCallback;
00727         break;
00728 
00729       default :
00730         /* Return error status */
00731         status =  HAL_ERROR;
00732         break;
00733     }
00734   }
00735   else if (heth->State == HAL_ETH_STATE_RESET)
00736   {
00737     switch (CallbackID)
00738     {
00739       case HAL_ETH_MSPINIT_CB_ID :
00740         heth->MspInitCallback = pCallback;
00741         break;
00742 
00743       case HAL_ETH_MSPDEINIT_CB_ID :
00744         heth->MspDeInitCallback = pCallback;
00745         break;
00746 
00747       default :
00748         /* Return error status */
00749         status =  HAL_ERROR;
00750         break;
00751     }
00752   }
00753   else
00754   {
00755     /* Return error status */
00756     status =  HAL_ERROR;
00757   }
00758 
00759   /* Release Lock */
00760   __HAL_UNLOCK(heth);
00761 
00762   return status;
00763 }
00764 
00765 /**
00766   * @brief  Unregister an ETH Callback
00767   *         ETH callabck is redirected to the weak predefined callback
00768   * @param heth eth handle
00769   * @param CallbackID ID of the callback to be unregistered
00770   *        This parameter can be one of the following values:
00771   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
00772   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
00773   *          @arg @ref HAL_ETH_DMA_ERROR_CB_ID      DMA Error Callback ID
00774   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
00775   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
00776   * @retval status
00777   */
00778 HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
00779 {
00780   HAL_StatusTypeDef status = HAL_OK;
00781 
00782   /* Process locked */
00783   __HAL_LOCK(heth);
00784 
00785   if (heth->State == HAL_ETH_STATE_READY)
00786   {
00787     switch (CallbackID)
00788     {
00789       case HAL_ETH_TX_COMPLETE_CB_ID :
00790         heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
00791         break;
00792 
00793       case HAL_ETH_RX_COMPLETE_CB_ID :
00794         heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
00795         break;
00796 
00797       case HAL_ETH_DMA_ERROR_CB_ID :
00798         heth->DMAErrorCallback = HAL_ETH_ErrorCallback;
00799         break;
00800 
00801       case HAL_ETH_MSPINIT_CB_ID :
00802         heth->MspInitCallback = HAL_ETH_MspInit;
00803         break;
00804 
00805       case HAL_ETH_MSPDEINIT_CB_ID :
00806         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
00807         break;
00808 
00809       default :
00810         /* Return error status */
00811         status =  HAL_ERROR;
00812         break;
00813     }
00814   }
00815   else if (heth->State == HAL_ETH_STATE_RESET)
00816   {
00817     switch (CallbackID)
00818     {
00819       case HAL_ETH_MSPINIT_CB_ID :
00820         heth->MspInitCallback = HAL_ETH_MspInit;
00821         break;
00822 
00823       case HAL_ETH_MSPDEINIT_CB_ID :
00824         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
00825         break;
00826 
00827       default :
00828         /* Return error status */
00829         status =  HAL_ERROR;
00830         break;
00831     }
00832   }
00833   else
00834   {
00835     /* Return error status */
00836     status =  HAL_ERROR;
00837   }
00838 
00839   /* Release Lock */
00840   __HAL_UNLOCK(heth);
00841 
00842   return status;
00843 }
00844 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
00845 
00846 /**
00847   * @}
00848   */
00849 
00850 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
00851   *  @brief   Data transfers functions
00852   *
00853   @verbatim
00854   ==============================================================================
00855                           ##### IO operation functions #####
00856   ==============================================================================
00857   [..]  This section provides functions allowing to:
00858         (+) Transmit a frame
00859             HAL_ETH_TransmitFrame();
00860         (+) Receive a frame
00861             HAL_ETH_GetReceivedFrame();
00862             HAL_ETH_GetReceivedFrame_IT();
00863         (+) Read from an External PHY register
00864             HAL_ETH_ReadPHYRegister();
00865         (+) Write to an External PHY register
00866             HAL_ETH_WritePHYRegister();
00867 
00868   @endverbatim
00869 
00870   * @{
00871   */
00872 
00873 /**
00874   * @brief  Sends an Ethernet frame.
00875   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
00876   *         the configuration information for ETHERNET module
00877   * @param  FrameLength: Amount of data to be sent
00878   * @retval HAL status
00879   */
00880 HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
00881 {
00882   uint32_t bufcount = 0U, size = 0U, i = 0U;
00883 
00884   /* Process Locked */
00885   __HAL_LOCK(heth);
00886 
00887   /* Set the ETH peripheral state to BUSY */
00888   heth->State = HAL_ETH_STATE_BUSY;
00889 
00890   if (FrameLength == 0U)
00891   {
00892     /* Set ETH HAL state to READY */
00893     heth->State = HAL_ETH_STATE_READY;
00894 
00895     /* Process Unlocked */
00896     __HAL_UNLOCK(heth);
00897 
00898     return  HAL_ERROR;
00899   }
00900 
00901   /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
00902   if (((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
00903   {
00904     /* OWN bit set */
00905     heth->State = HAL_ETH_STATE_BUSY_TX;
00906 
00907     /* Process Unlocked */
00908     __HAL_UNLOCK(heth);
00909 
00910     return HAL_ERROR;
00911   }
00912 
00913   /* Get the number of needed Tx buffers for the current frame */
00914   if (FrameLength > ETH_TX_BUF_SIZE)
00915   {
00916     bufcount = FrameLength / ETH_TX_BUF_SIZE;
00917     if (FrameLength % ETH_TX_BUF_SIZE)
00918     {
00919       bufcount++;
00920     }
00921   }
00922   else
00923   {
00924     bufcount = 1U;
00925   }
00926   if (bufcount == 1U)
00927   {
00928     /* Set LAST and FIRST segment */
00929     heth->TxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
00930     /* Set frame size */
00931     heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1);
00932     /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
00933     heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
00934     /* Point to next descriptor */
00935     heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
00936   }
00937   else
00938   {
00939     for (i = 0U; i < bufcount; i++)
00940     {
00941       /* Clear FIRST and LAST segment bits */
00942       heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
00943 
00944       if (i == 0U)
00945       {
00946         /* Setting the first segment bit */
00947         heth->TxDesc->Status |= ETH_DMATXDESC_FS;
00948       }
00949 
00950       /* Program size */
00951       heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
00952 
00953       if (i == (bufcount - 1U))
00954       {
00955         /* Setting the last segment bit */
00956         heth->TxDesc->Status |= ETH_DMATXDESC_LS;
00957         size = FrameLength - (bufcount - 1U) * ETH_TX_BUF_SIZE;
00958         heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
00959       }
00960 
00961       /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
00962       heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
00963       /* point to next descriptor */
00964       heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
00965     }
00966   }
00967 
00968   /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
00969   if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
00970   {
00971     /* Clear TBUS ETHERNET DMA flag */
00972     (heth->Instance)->DMASR = ETH_DMASR_TBUS;
00973     /* Resume DMA transmission*/
00974     (heth->Instance)->DMATPDR = 0U;
00975   }
00976 
00977   /* Set ETH HAL State to Ready */
00978   heth->State = HAL_ETH_STATE_READY;
00979 
00980   /* Process Unlocked */
00981   __HAL_UNLOCK(heth);
00982 
00983   /* Return function status */
00984   return HAL_OK;
00985 }
00986 
00987 /**
00988   * @brief  Checks for received frames.
00989   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
00990   *         the configuration information for ETHERNET module
00991   * @retval HAL status
00992   */
00993 HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth)
00994 {
00995   uint32_t framelength = 0U;
00996 
00997   /* Process Locked */
00998   __HAL_LOCK(heth);
00999 
01000   /* Check the ETH state to BUSY */
01001   heth->State = HAL_ETH_STATE_BUSY;
01002 
01003   /* Check if segment is not owned by DMA */
01004   /* (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) */
01005   if (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET))
01006   {
01007     /* Check if last segment */
01008     if (((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET))
01009     {
01010       /* increment segment count */
01011       (heth->RxFrameInfos).SegCount++;
01012 
01013       /* Check if last segment is first segment: one segment contains the frame */
01014       if ((heth->RxFrameInfos).SegCount == 1U)
01015       {
01016         (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
01017       }
01018 
01019       heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
01020 
01021       /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
01022       framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
01023       heth->RxFrameInfos.length = framelength;
01024 
01025       /* Get the address of the buffer start address */
01026       heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
01027       /* point to next descriptor */
01028       heth->RxDesc = (ETH_DMADescTypeDef *)((heth->RxDesc)->Buffer2NextDescAddr);
01029 
01030       /* Set HAL State to Ready */
01031       heth->State = HAL_ETH_STATE_READY;
01032 
01033       /* Process Unlocked */
01034       __HAL_UNLOCK(heth);
01035 
01036       /* Return function status */
01037       return HAL_OK;
01038     }
01039     /* Check if first segment */
01040     else if ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET)
01041     {
01042       (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
01043       (heth->RxFrameInfos).LSRxDesc = NULL;
01044       (heth->RxFrameInfos).SegCount = 1U;
01045       /* Point to next descriptor */
01046       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
01047     }
01048     /* Check if intermediate segment */
01049     else
01050     {
01051       (heth->RxFrameInfos).SegCount++;
01052       /* Point to next descriptor */
01053       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
01054     }
01055   }
01056 
01057   /* Set ETH HAL State to Ready */
01058   heth->State = HAL_ETH_STATE_READY;
01059 
01060   /* Process Unlocked */
01061   __HAL_UNLOCK(heth);
01062 
01063   /* Return function status */
01064   return HAL_ERROR;
01065 }
01066 
01067 /**
01068   * @brief  Gets the Received frame in interrupt mode.
01069   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01070   *         the configuration information for ETHERNET module
01071   * @retval HAL status
01072   */
01073 HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth)
01074 {
01075   uint32_t descriptorscancounter = 0U;
01076 
01077   /* Process Locked */
01078   __HAL_LOCK(heth);
01079 
01080   /* Set ETH HAL State to BUSY */
01081   heth->State = HAL_ETH_STATE_BUSY;
01082 
01083   /* Scan descriptors owned by CPU */
01084   while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (descriptorscancounter < ETH_RXBUFNB))
01085   {
01086     /* Just for security */
01087     descriptorscancounter++;
01088 
01089     /* Check if first segment in frame */
01090     /* ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)) */
01091     if ((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == (uint32_t)ETH_DMARXDESC_FS)
01092     {
01093       heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
01094       heth->RxFrameInfos.SegCount = 1U;
01095       /* Point to next descriptor */
01096       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
01097     }
01098     /* Check if intermediate segment */
01099     /* ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)&& ((heth->RxDesc->Status & ETH_DMARXDESC_FS) == (uint32_t)RESET)) */
01100     else if ((heth->RxDesc->Status & (ETH_DMARXDESC_LS | ETH_DMARXDESC_FS)) == (uint32_t)RESET)
01101     {
01102       /* Increment segment count */
01103       (heth->RxFrameInfos.SegCount)++;
01104       /* Point to next descriptor */
01105       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
01106     }
01107     /* Should be last segment */
01108     else
01109     {
01110       /* Last segment */
01111       heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
01112 
01113       /* Increment segment count */
01114       (heth->RxFrameInfos.SegCount)++;
01115 
01116       /* Check if last segment is first segment: one segment contains the frame */
01117       if ((heth->RxFrameInfos.SegCount) == 1U)
01118       {
01119         heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
01120       }
01121 
01122       /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
01123       heth->RxFrameInfos.length = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
01124 
01125       /* Get the address of the buffer start address */
01126       heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
01127 
01128       /* Point to next descriptor */
01129       heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
01130 
01131       /* Set HAL State to Ready */
01132       heth->State = HAL_ETH_STATE_READY;
01133 
01134       /* Process Unlocked */
01135       __HAL_UNLOCK(heth);
01136 
01137       /* Return function status */
01138       return HAL_OK;
01139     }
01140   }
01141 
01142   /* Set HAL State to Ready */
01143   heth->State = HAL_ETH_STATE_READY;
01144 
01145   /* Process Unlocked */
01146   __HAL_UNLOCK(heth);
01147 
01148   /* Return function status */
01149   return HAL_ERROR;
01150 }
01151 
01152 /**
01153   * @brief  This function handles ETH interrupt request.
01154   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01155   *         the configuration information for ETHERNET module
01156   * @retval HAL status
01157   */
01158 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
01159 {
01160   /* Frame received */
01161   if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R))
01162   {
01163 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
01164     /*Call registered Receive complete callback*/
01165     heth->RxCpltCallback(heth);
01166 #else
01167     /* Receive complete callback */
01168     HAL_ETH_RxCpltCallback(heth);
01169 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
01170 
01171     /* Clear the Eth DMA Rx IT pending bits */
01172     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R);
01173 
01174     /* Set HAL State to Ready */
01175     heth->State = HAL_ETH_STATE_READY;
01176 
01177     /* Process Unlocked */
01178     __HAL_UNLOCK(heth);
01179 
01180   }
01181   /* Frame transmitted */
01182   else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T))
01183   {
01184 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
01185     /*  Call resgistered Transfer complete callback*/
01186     heth->TxCpltCallback(heth);
01187 #else
01188     /* Transfer complete callback */
01189     HAL_ETH_TxCpltCallback(heth);
01190 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
01191 
01192     /* Clear the Eth DMA Tx IT pending bits */
01193     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T);
01194 
01195     /* Set HAL State to Ready */
01196     heth->State = HAL_ETH_STATE_READY;
01197 
01198     /* Process Unlocked */
01199     __HAL_UNLOCK(heth);
01200   }
01201 
01202   /* Clear the interrupt flags */
01203   __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS);
01204 
01205   /* ETH DMA Error */
01206   if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS))
01207   {
01208 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
01209     heth->DMAErrorCallback(heth);
01210 #else
01211     /* Ethernet Error callback */
01212     HAL_ETH_ErrorCallback(heth);
01213 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
01214 
01215     /* Clear the interrupt flags */
01216     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS);
01217 
01218     /* Set HAL State to Ready */
01219     heth->State = HAL_ETH_STATE_READY;
01220 
01221     /* Process Unlocked */
01222     __HAL_UNLOCK(heth);
01223   }
01224 }
01225 
01226 /**
01227   * @brief  Tx Transfer completed callbacks.
01228   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01229   *         the configuration information for ETHERNET module
01230   * @retval None
01231   */
01232 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
01233 {
01234   /* Prevent unused argument(s) compilation warning */
01235   UNUSED(heth);
01236   /* NOTE : This function Should not be modified, when the callback is needed,
01237   the HAL_ETH_TxCpltCallback could be implemented in the user file
01238   */
01239 }
01240 
01241 /**
01242   * @brief  Rx Transfer completed callbacks.
01243   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01244   *         the configuration information for ETHERNET module
01245   * @retval None
01246   */
01247 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
01248 {
01249   /* Prevent unused argument(s) compilation warning */
01250   UNUSED(heth);
01251   /* NOTE : This function Should not be modified, when the callback is needed,
01252   the HAL_ETH_TxCpltCallback could be implemented in the user file
01253   */
01254 }
01255 
01256 /**
01257   * @brief  Ethernet transfer error callbacks
01258   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01259   *         the configuration information for ETHERNET module
01260   * @retval None
01261   */
01262 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
01263 {
01264   /* Prevent unused argument(s) compilation warning */
01265   UNUSED(heth);
01266   /* NOTE : This function Should not be modified, when the callback is needed,
01267   the HAL_ETH_TxCpltCallback could be implemented in the user file
01268   */
01269 }
01270 
01271 /**
01272   * @brief  Reads a PHY register
01273   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01274   *         the configuration information for ETHERNET module
01275   * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
01276   *                This parameter can be one of the following values:
01277   *                   PHY_BCR: Transceiver Basic Control Register,
01278   *                   PHY_BSR: Transceiver Basic Status Register.
01279   *                   More PHY register could be read depending on the used PHY
01280   * @param RegValue: PHY register value
01281   * @retval HAL status
01282   */
01283 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
01284 {
01285   uint32_t tmpreg1 = 0U;
01286   uint32_t tickstart = 0U;
01287 
01288   /* Check parameters */
01289   assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
01290 
01291   /* Check the ETH peripheral state */
01292   if (heth->State == HAL_ETH_STATE_BUSY_RD)
01293   {
01294     return HAL_BUSY;
01295   }
01296   /* Set ETH HAL State to BUSY_RD */
01297   heth->State = HAL_ETH_STATE_BUSY_RD;
01298 
01299   /* Get the ETHERNET MACMIIAR value */
01300   tmpreg1 = heth->Instance->MACMIIAR;
01301 
01302   /* Keep only the CSR Clock Range CR[2:0] bits value */
01303   tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
01304 
01305   /* Prepare the MII address register value */
01306   tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address   */
01307   tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR);                /* Set the PHY register address */
01308   tmpreg1 &= ~ETH_MACMIIAR_MW;                                            /* Set the read mode            */
01309   tmpreg1 |= ETH_MACMIIAR_MB;                                             /* Set the MII Busy bit         */
01310 
01311   /* Write the result value into the MII Address register */
01312   heth->Instance->MACMIIAR = tmpreg1;
01313 
01314   /* Get tick */
01315   tickstart = HAL_GetTick();
01316 
01317   /* Check for the Busy flag */
01318   while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
01319   {
01320     /* Check for the Timeout */
01321     if ((HAL_GetTick() - tickstart) > PHY_READ_TO)
01322     {
01323       heth->State = HAL_ETH_STATE_READY;
01324 
01325       /* Process Unlocked */
01326       __HAL_UNLOCK(heth);
01327 
01328       return HAL_TIMEOUT;
01329     }
01330 
01331     tmpreg1 = heth->Instance->MACMIIAR;
01332   }
01333 
01334   /* Get MACMIIDR value */
01335   *RegValue = (uint16_t)(heth->Instance->MACMIIDR);
01336 
01337   /* Set ETH HAL State to READY */
01338   heth->State = HAL_ETH_STATE_READY;
01339 
01340   /* Return function status */
01341   return HAL_OK;
01342 }
01343 
01344 /**
01345   * @brief  Writes to a PHY register.
01346   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01347   *         the configuration information for ETHERNET module
01348   * @param  PHYReg: PHY register address, is the index of one of the 32 PHY register.
01349   *          This parameter can be one of the following values:
01350   *             PHY_BCR: Transceiver Control Register.
01351   *             More PHY register could be written depending on the used PHY
01352   * @param  RegValue: the value to write
01353   * @retval HAL status
01354   */
01355 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
01356 {
01357   uint32_t tmpreg1 = 0U;
01358   uint32_t tickstart = 0U;
01359 
01360   /* Check parameters */
01361   assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
01362 
01363   /* Check the ETH peripheral state */
01364   if (heth->State == HAL_ETH_STATE_BUSY_WR)
01365   {
01366     return HAL_BUSY;
01367   }
01368   /* Set ETH HAL State to BUSY_WR */
01369   heth->State = HAL_ETH_STATE_BUSY_WR;
01370 
01371   /* Get the ETHERNET MACMIIAR value */
01372   tmpreg1 = heth->Instance->MACMIIAR;
01373 
01374   /* Keep only the CSR Clock Range CR[2:0] bits value */
01375   tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
01376 
01377   /* Prepare the MII register address value */
01378   tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
01379   tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR);              /* Set the PHY register address */
01380   tmpreg1 |= ETH_MACMIIAR_MW;                                           /* Set the write mode */
01381   tmpreg1 |= ETH_MACMIIAR_MB;                                           /* Set the MII Busy bit */
01382 
01383   /* Give the value to the MII data register */
01384   heth->Instance->MACMIIDR = (uint16_t)RegValue;
01385 
01386   /* Write the result value into the MII Address register */
01387   heth->Instance->MACMIIAR = tmpreg1;
01388 
01389   /* Get tick */
01390   tickstart = HAL_GetTick();
01391 
01392   /* Check for the Busy flag */
01393   while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
01394   {
01395     /* Check for the Timeout */
01396     if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO)
01397     {
01398       heth->State = HAL_ETH_STATE_READY;
01399 
01400       /* Process Unlocked */
01401       __HAL_UNLOCK(heth);
01402 
01403       return HAL_TIMEOUT;
01404     }
01405 
01406     tmpreg1 = heth->Instance->MACMIIAR;
01407   }
01408 
01409   /* Set ETH HAL State to READY */
01410   heth->State = HAL_ETH_STATE_READY;
01411 
01412   /* Return function status */
01413   return HAL_OK;
01414 }
01415 
01416 /**
01417   * @}
01418   */
01419 
01420 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
01421  *  @brief    Peripheral Control functions
01422  *
01423 @verbatim
01424  ===============================================================================
01425                   ##### Peripheral Control functions #####
01426  ===============================================================================
01427     [..]  This section provides functions allowing to:
01428       (+) Enable MAC and DMA transmission and reception.
01429           HAL_ETH_Start();
01430       (+) Disable MAC and DMA transmission and reception.
01431           HAL_ETH_Stop();
01432       (+) Set the MAC configuration in runtime mode
01433           HAL_ETH_ConfigMAC();
01434       (+) Set the DMA configuration in runtime mode
01435           HAL_ETH_ConfigDMA();
01436 
01437 @endverbatim
01438   * @{
01439   */
01440 
01441 /**
01442  * @brief  Enables Ethernet MAC and DMA reception/transmission
01443  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01444  *         the configuration information for ETHERNET module
01445  * @retval HAL status
01446  */
01447 HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
01448 {
01449   /* Process Locked */
01450   __HAL_LOCK(heth);
01451 
01452   /* Set the ETH peripheral state to BUSY */
01453   heth->State = HAL_ETH_STATE_BUSY;
01454 
01455   /* Enable transmit state machine of the MAC for transmission on the MII */
01456   ETH_MACTransmissionEnable(heth);
01457 
01458   /* Enable receive state machine of the MAC for reception from the MII */
01459   ETH_MACReceptionEnable(heth);
01460 
01461   /* Flush Transmit FIFO */
01462   ETH_FlushTransmitFIFO(heth);
01463 
01464   /* Start DMA transmission */
01465   ETH_DMATransmissionEnable(heth);
01466 
01467   /* Start DMA reception */
01468   ETH_DMAReceptionEnable(heth);
01469 
01470   /* Set the ETH state to READY*/
01471   heth->State = HAL_ETH_STATE_READY;
01472 
01473   /* Process Unlocked */
01474   __HAL_UNLOCK(heth);
01475 
01476   /* Return function status */
01477   return HAL_OK;
01478 }
01479 
01480 /**
01481   * @brief  Stop Ethernet MAC and DMA reception/transmission
01482   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01483   *         the configuration information for ETHERNET module
01484   * @retval HAL status
01485   */
01486 HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
01487 {
01488   /* Process Locked */
01489   __HAL_LOCK(heth);
01490 
01491   /* Set the ETH peripheral state to BUSY */
01492   heth->State = HAL_ETH_STATE_BUSY;
01493 
01494   /* Stop DMA transmission */
01495   ETH_DMATransmissionDisable(heth);
01496 
01497   /* Stop DMA reception */
01498   ETH_DMAReceptionDisable(heth);
01499 
01500   /* Disable receive state machine of the MAC for reception from the MII */
01501   ETH_MACReceptionDisable(heth);
01502 
01503   /* Flush Transmit FIFO */
01504   ETH_FlushTransmitFIFO(heth);
01505 
01506   /* Disable transmit state machine of the MAC for transmission on the MII */
01507   ETH_MACTransmissionDisable(heth);
01508 
01509   /* Set the ETH state*/
01510   heth->State = HAL_ETH_STATE_READY;
01511 
01512   /* Process Unlocked */
01513   __HAL_UNLOCK(heth);
01514 
01515   /* Return function status */
01516   return HAL_OK;
01517 }
01518 
01519 /**
01520   * @brief  Set ETH MAC Configuration.
01521   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01522   *         the configuration information for ETHERNET module
01523   * @param  macconf: MAC Configuration structure
01524   * @retval HAL status
01525   */
01526 HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
01527 {
01528   uint32_t tmpreg1 = 0U;
01529 
01530   /* Process Locked */
01531   __HAL_LOCK(heth);
01532 
01533   /* Set the ETH peripheral state to BUSY */
01534   heth->State = HAL_ETH_STATE_BUSY;
01535 
01536   assert_param(IS_ETH_SPEED(heth->Init.Speed));
01537   assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
01538 
01539   if (macconf != NULL)
01540   {
01541     /* Check the parameters */
01542     assert_param(IS_ETH_WATCHDOG(macconf->Watchdog));
01543     assert_param(IS_ETH_JABBER(macconf->Jabber));
01544     assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap));
01545     assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense));
01546     assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn));
01547     assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode));
01548     assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload));
01549     assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission));
01550     assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip));
01551     assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit));
01552     assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck));
01553     assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll));
01554     assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter));
01555     assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames));
01556     assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception));
01557     assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter));
01558     assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode));
01559     assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter));
01560     assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter));
01561     assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime));
01562     assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause));
01563     assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold));
01564     assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect));
01565     assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl));
01566     assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl));
01567     assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison));
01568     assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier));
01569 
01570     /*------------------------ ETHERNET MACCR Configuration --------------------*/
01571     /* Get the ETHERNET MACCR value */
01572     tmpreg1 = (heth->Instance)->MACCR;
01573     /* Clear WD, PCE, PS, TE and RE bits */
01574     tmpreg1 &= ETH_MACCR_CLEAR_MASK;
01575 
01576     tmpreg1 |= (uint32_t)(macconf->Watchdog |
01577                           macconf->Jabber |
01578                           macconf->InterFrameGap |
01579                           macconf->CarrierSense |
01580                           (heth->Init).Speed |
01581                           macconf->ReceiveOwn |
01582                           macconf->LoopbackMode |
01583                           (heth->Init).DuplexMode |
01584                           macconf->ChecksumOffload |
01585                           macconf->RetryTransmission |
01586                           macconf->AutomaticPadCRCStrip |
01587                           macconf->BackOffLimit |
01588                           macconf->DeferralCheck);
01589 
01590     /* Write to ETHERNET MACCR */
01591     (heth->Instance)->MACCR = (uint32_t)tmpreg1;
01592 
01593     /* Wait until the write operation will be taken into account :
01594     at least four TX_CLK/RX_CLK clock cycles */
01595     tmpreg1 = (heth->Instance)->MACCR;
01596     HAL_Delay(ETH_REG_WRITE_DELAY);
01597     (heth->Instance)->MACCR = tmpreg1;
01598 
01599     /*----------------------- ETHERNET MACFFR Configuration --------------------*/
01600     /* Write to ETHERNET MACFFR */
01601     (heth->Instance)->MACFFR = (uint32_t)(macconf->ReceiveAll |
01602                                           macconf->SourceAddrFilter |
01603                                           macconf->PassControlFrames |
01604                                           macconf->BroadcastFramesReception |
01605                                           macconf->DestinationAddrFilter |
01606                                           macconf->PromiscuousMode |
01607                                           macconf->MulticastFramesFilter |
01608                                           macconf->UnicastFramesFilter);
01609 
01610     /* Wait until the write operation will be taken into account :
01611     at least four TX_CLK/RX_CLK clock cycles */
01612     tmpreg1 = (heth->Instance)->MACFFR;
01613     HAL_Delay(ETH_REG_WRITE_DELAY);
01614     (heth->Instance)->MACFFR = tmpreg1;
01615 
01616     /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
01617     /* Write to ETHERNET MACHTHR */
01618     (heth->Instance)->MACHTHR = (uint32_t)macconf->HashTableHigh;
01619 
01620     /* Write to ETHERNET MACHTLR */
01621     (heth->Instance)->MACHTLR = (uint32_t)macconf->HashTableLow;
01622     /*----------------------- ETHERNET MACFCR Configuration --------------------*/
01623 
01624     /* Get the ETHERNET MACFCR value */
01625     tmpreg1 = (heth->Instance)->MACFCR;
01626     /* Clear xx bits */
01627     tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
01628 
01629     tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) |
01630                           macconf->ZeroQuantaPause |
01631                           macconf->PauseLowThreshold |
01632                           macconf->UnicastPauseFrameDetect |
01633                           macconf->ReceiveFlowControl |
01634                           macconf->TransmitFlowControl);
01635 
01636     /* Write to ETHERNET MACFCR */
01637     (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
01638 
01639     /* Wait until the write operation will be taken into account :
01640     at least four TX_CLK/RX_CLK clock cycles */
01641     tmpreg1 = (heth->Instance)->MACFCR;
01642     HAL_Delay(ETH_REG_WRITE_DELAY);
01643     (heth->Instance)->MACFCR = tmpreg1;
01644 
01645     /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
01646     (heth->Instance)->MACVLANTR = (uint32_t)(macconf->VLANTagComparison |
01647                                              macconf->VLANTagIdentifier);
01648 
01649     /* Wait until the write operation will be taken into account :
01650     at least four TX_CLK/RX_CLK clock cycles */
01651     tmpreg1 = (heth->Instance)->MACVLANTR;
01652     HAL_Delay(ETH_REG_WRITE_DELAY);
01653     (heth->Instance)->MACVLANTR = tmpreg1;
01654   }
01655   else /* macconf == NULL : here we just configure Speed and Duplex mode */
01656   {
01657     /*------------------------ ETHERNET MACCR Configuration --------------------*/
01658     /* Get the ETHERNET MACCR value */
01659     tmpreg1 = (heth->Instance)->MACCR;
01660 
01661     /* Clear FES and DM bits */
01662     tmpreg1 &= ~(0x00004800U);
01663 
01664     tmpreg1 |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
01665 
01666     /* Write to ETHERNET MACCR */
01667     (heth->Instance)->MACCR = (uint32_t)tmpreg1;
01668 
01669     /* Wait until the write operation will be taken into account:
01670     at least four TX_CLK/RX_CLK clock cycles */
01671     tmpreg1 = (heth->Instance)->MACCR;
01672     HAL_Delay(ETH_REG_WRITE_DELAY);
01673     (heth->Instance)->MACCR = tmpreg1;
01674   }
01675 
01676   /* Set the ETH state to Ready */
01677   heth->State = HAL_ETH_STATE_READY;
01678 
01679   /* Process Unlocked */
01680   __HAL_UNLOCK(heth);
01681 
01682   /* Return function status */
01683   return HAL_OK;
01684 }
01685 
01686 /**
01687   * @brief  Sets ETH DMA Configuration.
01688   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01689   *         the configuration information for ETHERNET module
01690   * @param  dmaconf: DMA Configuration structure
01691   * @retval HAL status
01692   */
01693 HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
01694 {
01695   uint32_t tmpreg1 = 0U;
01696 
01697   /* Process Locked */
01698   __HAL_LOCK(heth);
01699 
01700   /* Set the ETH peripheral state to BUSY */
01701   heth->State = HAL_ETH_STATE_BUSY;
01702 
01703   /* Check parameters */
01704   assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame));
01705   assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward));
01706   assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame));
01707   assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward));
01708   assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl));
01709   assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames));
01710   assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames));
01711   assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl));
01712   assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate));
01713   assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats));
01714   assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst));
01715   assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength));
01716   assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength));
01717   assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength));
01718   assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration));
01719 
01720   /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
01721   /* Get the ETHERNET DMAOMR value */
01722   tmpreg1 = (heth->Instance)->DMAOMR;
01723   /* Clear xx bits */
01724   tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
01725 
01726   tmpreg1 |= (uint32_t)(dmaconf->DropTCPIPChecksumErrorFrame |
01727                         dmaconf->ReceiveStoreForward |
01728                         dmaconf->FlushReceivedFrame |
01729                         dmaconf->TransmitStoreForward |
01730                         dmaconf->TransmitThresholdControl |
01731                         dmaconf->ForwardErrorFrames |
01732                         dmaconf->ForwardUndersizedGoodFrames |
01733                         dmaconf->ReceiveThresholdControl |
01734                         dmaconf->SecondFrameOperate);
01735 
01736   /* Write to ETHERNET DMAOMR */
01737   (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
01738 
01739   /* Wait until the write operation will be taken into account:
01740   at least four TX_CLK/RX_CLK clock cycles */
01741   tmpreg1 = (heth->Instance)->DMAOMR;
01742   HAL_Delay(ETH_REG_WRITE_DELAY);
01743   (heth->Instance)->DMAOMR = tmpreg1;
01744 
01745   /*----------------------- ETHERNET DMABMR Configuration --------------------*/
01746   (heth->Instance)->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats |
01747                                         dmaconf->FixedBurst |
01748                                         dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
01749                                         dmaconf->TxDMABurstLength |
01750                                         (dmaconf->DescriptorSkipLength << 2U) |
01751                                         dmaconf->DMAArbitration |
01752                                         ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
01753 
01754   /* Wait until the write operation will be taken into account:
01755      at least four TX_CLK/RX_CLK clock cycles */
01756   tmpreg1 = (heth->Instance)->DMABMR;
01757   HAL_Delay(ETH_REG_WRITE_DELAY);
01758   (heth->Instance)->DMABMR = tmpreg1;
01759 
01760   /* Set the ETH state to Ready */
01761   heth->State = HAL_ETH_STATE_READY;
01762 
01763   /* Process Unlocked */
01764   __HAL_UNLOCK(heth);
01765 
01766   /* Return function status */
01767   return HAL_OK;
01768 }
01769 
01770 /**
01771   * @}
01772   */
01773 
01774 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions
01775   *  @brief   Peripheral State functions
01776   *
01777   @verbatim
01778   ===============================================================================
01779                          ##### Peripheral State functions #####
01780   ===============================================================================
01781   [..]
01782   This subsection permits to get in run-time the status of the peripheral
01783   and the data flow.
01784        (+) Get the ETH handle state:
01785            HAL_ETH_GetState();
01786 
01787 
01788   @endverbatim
01789   * @{
01790   */
01791 
01792 /**
01793   * @brief  Return the ETH HAL state
01794   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01795   *         the configuration information for ETHERNET module
01796   * @retval HAL state
01797   */
01798 HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
01799 {
01800   /* Return ETH state */
01801   return heth->State;
01802 }
01803 
01804 /**
01805   * @}
01806   */
01807 
01808 /**
01809   * @}
01810   */
01811 
01812 /** @addtogroup ETH_Private_Functions
01813   * @{
01814   */
01815 
01816 /**
01817   * @brief  Configures Ethernet MAC and DMA with default parameters.
01818   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
01819   *         the configuration information for ETHERNET module
01820   * @param  err: Ethernet Init error
01821   * @retval HAL status
01822   */
01823 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
01824 {
01825   ETH_MACInitTypeDef macinit;
01826   ETH_DMAInitTypeDef dmainit;
01827   uint32_t tmpreg1 = 0U;
01828 
01829   if (err != ETH_SUCCESS) /* Auto-negotiation failed */
01830   {
01831     /* Set Ethernet duplex mode to Full-duplex */
01832     (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
01833 
01834     /* Set Ethernet speed to 100M */
01835     (heth->Init).Speed = ETH_SPEED_100M;
01836   }
01837 
01838   /* Ethernet MAC default initialization **************************************/
01839   macinit.Watchdog = ETH_WATCHDOG_ENABLE;
01840   macinit.Jabber = ETH_JABBER_ENABLE;
01841   macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
01842   macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
01843   macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
01844   macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
01845   if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
01846   {
01847     macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
01848   }
01849   else
01850   {
01851     macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
01852   }
01853   macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
01854   macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
01855   macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
01856   macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
01857   macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
01858   macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
01859   macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
01860   macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
01861   macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
01862   macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
01863   macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
01864   macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
01865   macinit.HashTableHigh = 0x0U;
01866   macinit.HashTableLow = 0x0U;
01867   macinit.PauseTime = 0x0U;
01868   macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
01869   macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
01870   macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
01871   macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
01872   macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
01873   macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
01874   macinit.VLANTagIdentifier = 0x0U;
01875 
01876   /*------------------------ ETHERNET MACCR Configuration --------------------*/
01877   /* Get the ETHERNET MACCR value */
01878   tmpreg1 = (heth->Instance)->MACCR;
01879   /* Clear WD, PCE, PS, TE and RE bits */
01880   tmpreg1 &= ETH_MACCR_CLEAR_MASK;
01881   /* Set the WD bit according to ETH Watchdog value */
01882   /* Set the JD: bit according to ETH Jabber value */
01883   /* Set the IFG bit according to ETH InterFrameGap value */
01884   /* Set the DCRS bit according to ETH CarrierSense value */
01885   /* Set the FES bit according to ETH Speed value */
01886   /* Set the DO bit according to ETH ReceiveOwn value */
01887   /* Set the LM bit according to ETH LoopbackMode value */
01888   /* Set the DM bit according to ETH Mode value */
01889   /* Set the IPCO bit according to ETH ChecksumOffload value */
01890   /* Set the DR bit according to ETH RetryTransmission value */
01891   /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
01892   /* Set the BL bit according to ETH BackOffLimit value */
01893   /* Set the DC bit according to ETH DeferralCheck value */
01894   tmpreg1 |= (uint32_t)(macinit.Watchdog |
01895                         macinit.Jabber |
01896                         macinit.InterFrameGap |
01897                         macinit.CarrierSense |
01898                         (heth->Init).Speed |
01899                         macinit.ReceiveOwn |
01900                         macinit.LoopbackMode |
01901                         (heth->Init).DuplexMode |
01902                         macinit.ChecksumOffload |
01903                         macinit.RetryTransmission |
01904                         macinit.AutomaticPadCRCStrip |
01905                         macinit.BackOffLimit |
01906                         macinit.DeferralCheck);
01907 
01908   /* Write to ETHERNET MACCR */
01909   (heth->Instance)->MACCR = (uint32_t)tmpreg1;
01910 
01911   /* Wait until the write operation will be taken into account:
01912      at least four TX_CLK/RX_CLK clock cycles */
01913   tmpreg1 = (heth->Instance)->MACCR;
01914   HAL_Delay(ETH_REG_WRITE_DELAY);
01915   (heth->Instance)->MACCR = tmpreg1;
01916 
01917   /*----------------------- ETHERNET MACFFR Configuration --------------------*/
01918   /* Set the RA bit according to ETH ReceiveAll value */
01919   /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
01920   /* Set the PCF bit according to ETH PassControlFrames value */
01921   /* Set the DBF bit according to ETH BroadcastFramesReception value */
01922   /* Set the DAIF bit according to ETH DestinationAddrFilter value */
01923   /* Set the PR bit according to ETH PromiscuousMode value */
01924   /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
01925   /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
01926   /* Write to ETHERNET MACFFR */
01927   (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
01928                                         macinit.SourceAddrFilter |
01929                                         macinit.PassControlFrames |
01930                                         macinit.BroadcastFramesReception |
01931                                         macinit.DestinationAddrFilter |
01932                                         macinit.PromiscuousMode |
01933                                         macinit.MulticastFramesFilter |
01934                                         macinit.UnicastFramesFilter);
01935 
01936   /* Wait until the write operation will be taken into account:
01937      at least four TX_CLK/RX_CLK clock cycles */
01938   tmpreg1 = (heth->Instance)->MACFFR;
01939   HAL_Delay(ETH_REG_WRITE_DELAY);
01940   (heth->Instance)->MACFFR = tmpreg1;
01941 
01942   /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
01943   /* Write to ETHERNET MACHTHR */
01944   (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
01945 
01946   /* Write to ETHERNET MACHTLR */
01947   (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;
01948   /*----------------------- ETHERNET MACFCR Configuration -------------------*/
01949 
01950   /* Get the ETHERNET MACFCR value */
01951   tmpreg1 = (heth->Instance)->MACFCR;
01952   /* Clear xx bits */
01953   tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
01954 
01955   /* Set the PT bit according to ETH PauseTime value */
01956   /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
01957   /* Set the PLT bit according to ETH PauseLowThreshold value */
01958   /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
01959   /* Set the RFE bit according to ETH ReceiveFlowControl value */
01960   /* Set the TFE bit according to ETH TransmitFlowControl value */
01961   tmpreg1 |= (uint32_t)((macinit.PauseTime << 16U) |
01962                         macinit.ZeroQuantaPause |
01963                         macinit.PauseLowThreshold |
01964                         macinit.UnicastPauseFrameDetect |
01965                         macinit.ReceiveFlowControl |
01966                         macinit.TransmitFlowControl);
01967 
01968   /* Write to ETHERNET MACFCR */
01969   (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
01970 
01971   /* Wait until the write operation will be taken into account:
01972   at least four TX_CLK/RX_CLK clock cycles */
01973   tmpreg1 = (heth->Instance)->MACFCR;
01974   HAL_Delay(ETH_REG_WRITE_DELAY);
01975   (heth->Instance)->MACFCR = tmpreg1;
01976 
01977   /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
01978   /* Set the ETV bit according to ETH VLANTagComparison value */
01979   /* Set the VL bit according to ETH VLANTagIdentifier value */
01980   (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
01981                                            macinit.VLANTagIdentifier);
01982 
01983   /* Wait until the write operation will be taken into account:
01984      at least four TX_CLK/RX_CLK clock cycles */
01985   tmpreg1 = (heth->Instance)->MACVLANTR;
01986   HAL_Delay(ETH_REG_WRITE_DELAY);
01987   (heth->Instance)->MACVLANTR = tmpreg1;
01988 
01989   /* Ethernet DMA default initialization ************************************/
01990   dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
01991   dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
01992   dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
01993   dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
01994   dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
01995   dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
01996   dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
01997   dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
01998   dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
01999   dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
02000   dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
02001   dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
02002   dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
02003   dmainit.DescriptorSkipLength = 0x0U;
02004   dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
02005 
02006   /* Get the ETHERNET DMAOMR value */
02007   tmpreg1 = (heth->Instance)->DMAOMR;
02008   /* Clear xx bits */
02009   tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
02010 
02011   /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
02012   /* Set the RSF bit according to ETH ReceiveStoreForward value */
02013   /* Set the DFF bit according to ETH FlushReceivedFrame value */
02014   /* Set the TSF bit according to ETH TransmitStoreForward value */
02015   /* Set the TTC bit according to ETH TransmitThresholdControl value */
02016   /* Set the FEF bit according to ETH ForwardErrorFrames value */
02017   /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
02018   /* Set the RTC bit according to ETH ReceiveThresholdControl value */
02019   /* Set the OSF bit according to ETH SecondFrameOperate value */
02020   tmpreg1 |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
02021                         dmainit.ReceiveStoreForward |
02022                         dmainit.FlushReceivedFrame |
02023                         dmainit.TransmitStoreForward |
02024                         dmainit.TransmitThresholdControl |
02025                         dmainit.ForwardErrorFrames |
02026                         dmainit.ForwardUndersizedGoodFrames |
02027                         dmainit.ReceiveThresholdControl |
02028                         dmainit.SecondFrameOperate);
02029 
02030   /* Write to ETHERNET DMAOMR */
02031   (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
02032 
02033   /* Wait until the write operation will be taken into account:
02034      at least four TX_CLK/RX_CLK clock cycles */
02035   tmpreg1 = (heth->Instance)->DMAOMR;
02036   HAL_Delay(ETH_REG_WRITE_DELAY);
02037   (heth->Instance)->DMAOMR = tmpreg1;
02038 
02039   /*----------------------- ETHERNET DMABMR Configuration ------------------*/
02040   /* Set the AAL bit according to ETH AddressAlignedBeats value */
02041   /* Set the FB bit according to ETH FixedBurst value */
02042   /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
02043   /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
02044   /* Set the DSL bit according to ETH DesciptorSkipLength value */
02045   /* Set the PR and DA bits according to ETH DMAArbitration value */
02046   (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
02047                                         dmainit.FixedBurst |
02048                                         dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
02049                                         dmainit.TxDMABurstLength |
02050                                         (dmainit.DescriptorSkipLength << 2U) |
02051                                         dmainit.DMAArbitration |
02052                                         ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
02053 
02054   /* Wait until the write operation will be taken into account:
02055      at least four TX_CLK/RX_CLK clock cycles */
02056   tmpreg1 = (heth->Instance)->DMABMR;
02057   HAL_Delay(ETH_REG_WRITE_DELAY);
02058   (heth->Instance)->DMABMR = tmpreg1;
02059 
02060   if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
02061   {
02062     /* Enable the Ethernet Rx Interrupt */
02063     __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
02064   }
02065 
02066   /* Initialize MAC address in ethernet MAC */
02067   ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
02068 }
02069 
02070 /**
02071   * @brief  Configures the selected MAC address.
02072   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02073   *         the configuration information for ETHERNET module
02074   * @param  MacAddr: The MAC address to configure
02075   *          This parameter can be one of the following values:
02076   *             @arg ETH_MAC_Address0: MAC Address0
02077   *             @arg ETH_MAC_Address1: MAC Address1
02078   *             @arg ETH_MAC_Address2: MAC Address2
02079   *             @arg ETH_MAC_Address3: MAC Address3
02080   * @param  Addr: Pointer to MAC address buffer data (6 bytes)
02081   * @retval HAL status
02082   */
02083 static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
02084 {
02085   uint32_t tmpreg1;
02086 
02087   /* Prevent unused argument(s) compilation warning */
02088   UNUSED(heth);
02089 
02090   /* Check the parameters */
02091   assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
02092 
02093   /* Calculate the selected MAC address high register */
02094   tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U];
02095   /* Load the selected MAC address high register */
02096   (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1;
02097   /* Calculate the selected MAC address low register */
02098   tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U];
02099 
02100   /* Load the selected MAC address low register */
02101   (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1;
02102 }
02103 
02104 /**
02105   * @brief  Enables the MAC transmission.
02106   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02107   *         the configuration information for ETHERNET module
02108   * @retval None
02109   */
02110 static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth)
02111 {
02112   __IO uint32_t tmpreg1 = 0U;
02113 
02114   /* Enable the MAC transmission */
02115   (heth->Instance)->MACCR |= ETH_MACCR_TE;
02116 
02117   /* Wait until the write operation will be taken into account:
02118      at least four TX_CLK/RX_CLK clock cycles */
02119   tmpreg1 = (heth->Instance)->MACCR;
02120   ETH_Delay(ETH_REG_WRITE_DELAY);
02121   (heth->Instance)->MACCR = tmpreg1;
02122 }
02123 
02124 /**
02125   * @brief  Disables the MAC transmission.
02126   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02127   *         the configuration information for ETHERNET module
02128   * @retval None
02129   */
02130 static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth)
02131 {
02132   __IO uint32_t tmpreg1 = 0U;
02133 
02134   /* Disable the MAC transmission */
02135   (heth->Instance)->MACCR &= ~ETH_MACCR_TE;
02136 
02137   /* Wait until the write operation will be taken into account:
02138      at least four TX_CLK/RX_CLK clock cycles */
02139   tmpreg1 = (heth->Instance)->MACCR;
02140   ETH_Delay(ETH_REG_WRITE_DELAY);
02141   (heth->Instance)->MACCR = tmpreg1;
02142 }
02143 
02144 /**
02145   * @brief  Enables the MAC reception.
02146   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02147   *         the configuration information for ETHERNET module
02148   * @retval None
02149   */
02150 static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth)
02151 {
02152   __IO uint32_t tmpreg1 = 0U;
02153 
02154   /* Enable the MAC reception */
02155   (heth->Instance)->MACCR |= ETH_MACCR_RE;
02156 
02157   /* Wait until the write operation will be taken into account:
02158      at least four TX_CLK/RX_CLK clock cycles */
02159   tmpreg1 = (heth->Instance)->MACCR;
02160   ETH_Delay(ETH_REG_WRITE_DELAY);
02161   (heth->Instance)->MACCR = tmpreg1;
02162 }
02163 
02164 /**
02165   * @brief  Disables the MAC reception.
02166   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02167   *         the configuration information for ETHERNET module
02168   * @retval None
02169   */
02170 static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth)
02171 {
02172   __IO uint32_t tmpreg1 = 0U;
02173 
02174   /* Disable the MAC reception */
02175   (heth->Instance)->MACCR &= ~ETH_MACCR_RE;
02176 
02177   /* Wait until the write operation will be taken into account:
02178      at least four TX_CLK/RX_CLK clock cycles */
02179   tmpreg1 = (heth->Instance)->MACCR;
02180   ETH_Delay(ETH_REG_WRITE_DELAY);
02181   (heth->Instance)->MACCR = tmpreg1;
02182 }
02183 
02184 /**
02185   * @brief  Enables the DMA transmission.
02186   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02187   *         the configuration information for ETHERNET module
02188   * @retval None
02189   */
02190 static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth)
02191 {
02192   /* Enable the DMA transmission */
02193   (heth->Instance)->DMAOMR |= ETH_DMAOMR_ST;
02194 }
02195 
02196 /**
02197   * @brief  Disables the DMA transmission.
02198   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02199   *         the configuration information for ETHERNET module
02200   * @retval None
02201   */
02202 static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth)
02203 {
02204   /* Disable the DMA transmission */
02205   (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_ST;
02206 }
02207 
02208 /**
02209   * @brief  Enables the DMA reception.
02210   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02211   *         the configuration information for ETHERNET module
02212   * @retval None
02213   */
02214 static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth)
02215 {
02216   /* Enable the DMA reception */
02217   (heth->Instance)->DMAOMR |= ETH_DMAOMR_SR;
02218 }
02219 
02220 /**
02221   * @brief  Disables the DMA reception.
02222   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02223   *         the configuration information for ETHERNET module
02224   * @retval None
02225   */
02226 static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth)
02227 {
02228   /* Disable the DMA reception */
02229   (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_SR;
02230 }
02231 
02232 /**
02233   * @brief  Clears the ETHERNET transmit FIFO.
02234   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
02235   *         the configuration information for ETHERNET module
02236   * @retval None
02237   */
02238 static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
02239 {
02240   __IO uint32_t tmpreg1 = 0U;
02241 
02242   /* Set the Flush Transmit FIFO bit */
02243   (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;
02244 
02245   /* Wait until the write operation will be taken into account:
02246      at least four TX_CLK/RX_CLK clock cycles */
02247   tmpreg1 = (heth->Instance)->DMAOMR;
02248   ETH_Delay(ETH_REG_WRITE_DELAY);
02249   (heth->Instance)->DMAOMR = tmpreg1;
02250 }
02251 
02252 /**
02253   * @brief  This function provides delay (in milliseconds) based on CPU cycles method.
02254   * @param  mdelay: specifies the delay time length, in milliseconds.
02255   * @retval None
02256   */
02257 static void ETH_Delay(uint32_t mdelay)
02258 {
02259   __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
02260   do
02261   {
02262     __NOP();
02263   }
02264   while (Delay --);
02265 }
02266 
02267 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
02268 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
02269 {
02270   /* Init the ETH Callback settings */
02271   heth->TxCpltCallback       = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback   */
02272   heth->RxCpltCallback       = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback   */
02273   heth->DMAErrorCallback     = HAL_ETH_ErrorCallback;  /* Legacy weak DMAErrorCallback */
02274 }
02275 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
02276 
02277 /**
02278   * @}
02279   */
02280 
02281 #endif /* ETH */
02282 
02283 #endif /* HAL_ETH_MODULE_ENABLED */
02284 /**
02285   * @}
02286   */
02287 
02288 /**
02289   * @}
02290   */
02291 
02292 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/