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