STM32F439xx HAL User Manual
|
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>© 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****/