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