1 /** 2 ****************************************************************************** 3 * @file stm32fxx_hal_eth.c 4 * @author MCD Application Team 5 * @version V1.3.2 6 * @date 26-June-2015 7 * @brief ETH HAL module driver. 8 * This file provides firmware functions to manage the following 9 * functionalities of the Ethernet (ETH) peripheral: 10 * + Initialization and de-initialization functions 11 * + IO operation functions 12 * + Peripheral Control functions 13 * + Peripheral State and Errors functions 14 * 15 * @verbatim 16 * ============================================================================== 17 ##### How to use this driver ##### 18 #####============================================================================== 19 #####[..] 20 #####(#)Declare a ETH_HandleTypeDef handle structure, for example: 21 ##### ETH_HandleTypeDef heth; 22 ##### 23 #####(#)Fill parameters of Init structure in heth handle 24 ##### 25 #####(#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) 26 ##### 27 #####(#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: 28 ##### (##) Enable the Ethernet interface clock using 29 ##### (+++) __HAL_RCC_ETHMAC_CLK_ENABLE(); 30 ##### (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE(); 31 ##### (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE(); 32 ##### 33 ##### (##) Initialize the related GPIO clocks 34 ##### (##) Configure Ethernet pin-out 35 ##### (##) Configure Ethernet NVIC interrupt (IT mode) 36 ##### 37 #####(#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers: 38 ##### (##) HAL_ETH_DMATxDescListInit(); for Transmission process 39 ##### (##) HAL_ETH_DMARxDescListInit(); for Reception process 40 ##### 41 #####(#)Enable MAC and DMA transmission and reception: 42 ##### (##) HAL_ETH_Start(); 43 ##### 44 #####(#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer 45 ##### the frame to MAC TX FIFO: 46 ##### (##) HAL_ETH_TransmitFrame(); 47 ##### 48 #####(#)Poll for a received frame in ETH RX DMA Descriptors and get received 49 ##### frame parameters 50 ##### (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop) 51 ##### 52 #####(#) Get a received frame when an ETH RX interrupt occurs: 53 ##### (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only) 54 ##### 55 #####(#) Communicate with external PHY device: 56 ##### (##) Read a specific register from the PHY 57 ##### HAL_ETH_ReadPHYRegister(); 58 ##### (##) Write data to a specific RHY register: 59 ##### HAL_ETH_WritePHYRegister(); 60 ##### 61 #####(#) Configure the Ethernet MAC after ETH peripheral initialization 62 ##### HAL_ETH_ConfigMAC(); all MAC parameters should be filled. 63 ##### 64 #####(#) Configure the Ethernet DMA after ETH peripheral initialization 65 ##### HAL_ETH_ConfigDMA(); all DMA parameters should be filled. 66 ##### 67 #####-@- The PTP protocol and the DMA descriptors ring mode are not supported 68 ##### in this driver 69 ##### 70 #####@endverbatim 71 ****************************************************************************** 72 * @attention 73 * 74 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 75 * 76 * Redistribution and use in source and binary forms, with or without modification, 77 * are permitted provided that the following conditions are met: 78 * 1. Redistributions of source code must retain the above copyright notice, 79 * this list of conditions and the following disclaimer. 80 * 2. Redistributions in binary form must reproduce the above copyright notice, 81 * this list of conditions and the following disclaimer in the documentation 82 * and/or other materials provided with the distribution. 83 * 3. Neither the name of STMicroelectronics nor the names of its contributors 84 * may be used to endorse or promote products derived from this software 85 * without specific prior written permission. 86 * 87 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 88 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 89 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 90 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 91 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 92 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 93 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 94 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 95 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 96 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 97 * 98 ****************************************************************************** 99 */ 100 101 /* Includes ------------------------------------------------------------------*/ 102 #include "stm32fxx_hal_eth.h" 103 104 #if defined( STM32F7xx ) 105 #include "stm32f7xx_hal.h" 106 #define stm_is_F7 1 107 #elif defined( STM32F4xx ) 108 #include "stm32f4xx_hal.h" 109 #define stm_is_F4 1 110 #elif defined( STM32F2xx ) 111 #include "stm32f2xx_hal.h" 112 #define stm_is_F2 1 113 #elif defined( STM32F1xx ) 114 #include "stm32f1xx_hal.h" 115 #define stm_is_F1 1 116 #else /* if defined( STM32F7xx ) */ 117 #error For what part should this be compiled? 118 #endif /* if defined( STM32F7xx ) */ 119 120 /** @addtogroup STM32F4xx_HAL_Driver 121 * @{ 122 */ 123 124 /** @defgroup ETH ETH 125 * @brief ETH HAL module driver 126 * @{ 127 */ 128 129 #if !defined( ARRAY_SIZE ) 130 #define ARRAY_SIZE( x ) ( sizeof( x ) / sizeof( x )[ 0 ] ) 131 #endif 132 133 #ifdef HAL_ETH_MODULE_ENABLED 134 135 #if ( stm_is_F1 != 0 || stm_is_F2 != 0 || stm_is_F4 != 0 || stm_is_F7 ) 136 137 /* Private typedef -----------------------------------------------------------*/ 138 /* Private define ------------------------------------------------------------*/ 139 140 /** @defgroup ETH_Private_Constants ETH Private Constants 141 * @{ 142 */ 143 /* Some macros have been renamed through time. */ 144 #ifndef ETH_MACMIIAR_CR_Div16 145 #define ETH_MACMIIAR_CR_Div16 ETH_MACMIIAR_CR_DIV16 146 #define ETH_MACMIIAR_CR_Div26 ETH_MACMIIAR_CR_DIV26 147 #define ETH_MACMIIAR_CR_Div42 ETH_MACMIIAR_CR_DIV42 148 #endif 149 150 /** 151 * @} 152 */ 153 /* Private macro -------------------------------------------------------------*/ 154 /* Private variables ---------------------------------------------------------*/ 155 /* Private function prototypes -----------------------------------------------*/ 156 157 /** @defgroup ETH_Private_Functions ETH Private Functions 158 * @{ 159 */ 160 static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth, 161 uint32_t err ); 162 static void ETH_MACAddressConfig( ETH_HandleTypeDef * heth, 163 uint32_t MacAddr, 164 uint8_t * Addr ); 165 static void ETH_MACReceptionEnable( ETH_HandleTypeDef * heth ); 166 static void ETH_MACReceptionDisable( ETH_HandleTypeDef * heth ); 167 static void ETH_MACTransmissionEnable( ETH_HandleTypeDef * heth ); 168 static void ETH_MACTransmissionDisable( ETH_HandleTypeDef * heth ); 169 static void ETH_DMATransmissionEnable( ETH_HandleTypeDef * heth ); 170 static void ETH_DMATransmissionDisable( ETH_HandleTypeDef * heth ); 171 static void ETH_DMAReceptionEnable( ETH_HandleTypeDef * heth ); 172 static void ETH_DMAReceptionDisable( ETH_HandleTypeDef * heth ); 173 static void ETH_FlushTransmitFIFO( ETH_HandleTypeDef * heth ); 174 175 /** 176 * @} 177 */ 178 /* Private functions ---------------------------------------------------------*/ 179 180 /** @defgroup ETH_Exported_Functions ETH Exported Functions 181 * @{ 182 */ 183 184 /** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions 185 * @brief Initialization and Configuration functions 186 * 187 * @verbatim 188 * =============================================================================== 189 ##### Initialization and de-initialization functions ##### 190 #####=============================================================================== 191 #####[..] This section provides functions allowing to: 192 #####(+) Initialize and configure the Ethernet peripheral 193 #####(+) De-initialize the Ethernet peripheral 194 ##### 195 #####@endverbatim 196 * @{ 197 */ 198 extern void vMACBProbePhy( void ); 199 200 /** 201 * @brief Initializes the Ethernet MAC and DMA according to default 202 * parameters. 203 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 204 * the configuration information for ETHERNET module 205 * @retval HAL status 206 */ HAL_ETH_Init(ETH_HandleTypeDef * heth)207 HAL_StatusTypeDef HAL_ETH_Init( ETH_HandleTypeDef * heth ) 208 { 209 uint32_t tmpreg = 0uL; 210 uint32_t hclk = 60000000uL; 211 uint32_t err = ETH_SUCCESS; 212 213 /* Check the ETH peripheral state */ 214 if( heth == NULL ) 215 { 216 return HAL_ERROR; 217 } 218 219 /* Check parameters */ 220 assert_param( IS_ETH_AUTONEGOTIATION( heth->Init.AutoNegotiation ) ); 221 assert_param( IS_ETH_RX_MODE( heth->Init.RxMode ) ); 222 assert_param( IS_ETH_CHECKSUM_MODE( heth->Init.ChecksumMode ) ); 223 assert_param( IS_ETH_MEDIA_INTERFACE( heth->Init.MediaInterface ) ); 224 225 if( heth->State == HAL_ETH_STATE_RESET ) 226 { 227 /* Init the low level hardware : GPIO, CLOCK, NVIC. */ 228 HAL_ETH_MspInit( heth ); 229 } 230 231 /* Enable SYSCFG Clock */ 232 __HAL_RCC_SYSCFG_CLK_ENABLE(); 233 234 /* Select MII or RMII Mode*/ 235 SYSCFG->PMC &= ~( SYSCFG_PMC_MII_RMII_SEL ); 236 SYSCFG->PMC |= ( uint32_t ) heth->Init.MediaInterface; 237 238 /* Ethernet Software reset */ 239 /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ 240 /* After reset all the registers holds their respective reset values */ 241 /* Also enable EDFE: Enhanced descriptor format enable. */ 242 heth->Instance->DMABMR |= ETH_DMABMR_SR | ETH_DMABMR_EDE; 243 244 /* Wait for software reset */ 245 while( ( heth->Instance->DMABMR & ETH_DMABMR_SR ) != ( uint32_t ) RESET ) 246 { 247 /* If your program hangs here, please check the value of 'ipconfigUSE_RMII'. */ 248 } 249 250 /*-------------------------------- MAC Initialization ----------------------*/ 251 /* Get the ETHERNET MACMIIAR value */ 252 tmpreg = heth->Instance->MACMIIAR; 253 /* Clear CSR Clock Range CR[2:0] bits */ 254 tmpreg &= ETH_MACMIIAR_CR_MASK; 255 256 /* Get hclk frequency value (e.g. 168,000,000) */ 257 hclk = HAL_RCC_GetHCLKFreq(); 258 #if !defined( STM32F2xx ) 259 /* Set CR bits depending on hclk value */ 260 if( ( hclk >= 20000000uL ) && ( hclk < 35000000uL ) ) 261 { 262 /* CSR Clock Range between 20-35 MHz */ 263 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div16; 264 } 265 else if( ( hclk >= 35000000uL ) && ( hclk < 60000000uL ) ) 266 { 267 /* CSR Clock Range between 35-60 MHz */ 268 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div26; 269 } 270 else 271 { 272 #if ( stm_is_F1 != 0 ) 273 { 274 /* The STM32F1xx has a frequency up to 72 MHz. */ 275 /* CSR Clock Range between 60-72 MHz */ 276 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div42; 277 } 278 #else 279 { 280 if( ( hclk >= 60000000uL ) && ( hclk < 100000000uL ) ) 281 { 282 /* CSR Clock Range between 60-100 MHz */ 283 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div42; 284 } 285 else if( ( hclk >= 100000000uL ) && ( hclk < 150000000uL ) ) 286 { 287 /* CSR Clock Range between 100-150 MHz */ 288 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div62; 289 } 290 else /* ( ( hclk >= 150000000uL ) && ( hclk <= 183000000uL ) ) */ 291 { 292 /* CSR Clock Range between 150-183 MHz */ 293 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div102; 294 } 295 } 296 #endif /* if ( stm_is_F1 != 0 ) */ 297 } 298 #else /* if !defined( STM32F2xx ) */ 299 /* Clock settings for STM32F2 only. */ 300 /* Set CR bits depending on hclk value */ 301 if( ( hclk >= 20000000U ) && ( hclk < 35000000U ) ) 302 { 303 /* CSR Clock Range between 20-35 MHz */ 304 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div16; 305 } 306 else if( ( hclk >= 35000000U ) && ( hclk < 60000000U ) ) 307 { 308 /* CSR Clock Range between 35-60 MHz */ 309 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div26; 310 } 311 else if( ( hclk >= 60000000U ) && ( hclk < 100000000U ) ) 312 { 313 /* CSR Clock Range between 60-100 MHz */ 314 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div42; 315 } 316 else /* ((hclk >= 100000000)&&(hclk < 120000000)) */ 317 { 318 /* CSR Clock Range between 100-120 MHz */ 319 tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div62; 320 } 321 #endif /* defined(STM32F2xx) */ 322 /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */ 323 heth->Instance->MACMIIAR = ( uint32_t ) tmpreg; 324 325 /* Initialise the MACB and set all PHY properties */ 326 vMACBProbePhy(); 327 328 /* Config MAC and DMA */ 329 ETH_MACDMAConfig( heth, err ); 330 331 /* Set ETH HAL State to Ready */ 332 heth->State = HAL_ETH_STATE_READY; 333 334 /* Return function status */ 335 return HAL_OK; 336 } 337 338 /** 339 * @brief De-Initializes the ETH peripheral. 340 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 341 * the configuration information for ETHERNET module 342 * @retval HAL status 343 */ HAL_ETH_DeInit(ETH_HandleTypeDef * heth)344 HAL_StatusTypeDef HAL_ETH_DeInit( ETH_HandleTypeDef * heth ) 345 { 346 /* Set the ETH peripheral state to BUSY */ 347 heth->State = HAL_ETH_STATE_BUSY; 348 349 /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ 350 HAL_ETH_MspDeInit( heth ); 351 352 /* Set ETH HAL state to Disabled */ 353 heth->State = HAL_ETH_STATE_RESET; 354 355 /* Release Lock */ 356 __HAL_UNLOCK( heth ); 357 358 /* Return function status */ 359 return HAL_OK; 360 } 361 362 /** 363 * @brief Initializes the ETH MSP. 364 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 365 * the configuration information for ETHERNET module 366 * @retval None 367 */ HAL_ETH_MspInit(ETH_HandleTypeDef * heth)368 __weak void HAL_ETH_MspInit( ETH_HandleTypeDef * heth ) 369 { 370 /* NOTE : This function Should not be modified, when the callback is needed, 371 * the HAL_ETH_MspInit could be implemented in the user file 372 */ 373 ( void ) heth; 374 } 375 376 /** 377 * @brief DeInitializes ETH MSP. 378 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 379 * the configuration information for ETHERNET module 380 * @retval None 381 */ HAL_ETH_MspDeInit(ETH_HandleTypeDef * heth)382 __weak void HAL_ETH_MspDeInit( ETH_HandleTypeDef * heth ) 383 { 384 /* NOTE : This function Should not be modified, when the callback is needed, 385 * the HAL_ETH_MspDeInit could be implemented in the user file 386 */ 387 ( void ) heth; 388 } 389 390 /** 391 * @} 392 */ 393 394 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions 395 * @brief Data transfers functions 396 * 397 * @verbatim 398 * ============================================================================== 399 ##### IO operation functions ##### 400 #####============================================================================== 401 #####[..] This section provides functions allowing to: 402 ##### (+) Transmit a frame 403 ##### HAL_ETH_TransmitFrame(); 404 ##### (+) Receive a frame 405 ##### HAL_ETH_GetReceivedFrame(); 406 ##### HAL_ETH_GetReceivedFrame_IT(); 407 ##### (+) Read from an External PHY register 408 ##### HAL_ETH_ReadPHYRegister(); 409 ##### (+) Write to an External PHY register 410 ##### HAL_ETH_WritePHYRegister(); 411 ##### 412 #####@endverbatim 413 ##### 414 * @{ 415 */ 416 417 #define ETH_DMA_ALL_INTS \ 418 ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_AIS | ETH_DMA_IT_ER | \ 419 ETH_DMA_IT_FBE | ETH_DMA_IT_ET | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \ 420 ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T ) 421 422 #define INT_MASK ( ( uint32_t ) ~( ETH_DMA_IT_TBU ) ) HAL_ETH_IRQHandler(ETH_HandleTypeDef * heth)423 void HAL_ETH_IRQHandler( ETH_HandleTypeDef * heth ) 424 { 425 uint32_t dmasr; 426 427 dmasr = heth->Instance->DMASR & ETH_DMA_ALL_INTS; 428 heth->Instance->DMASR = dmasr; 429 430 /* Frame received */ 431 if( ( dmasr & ( ETH_DMA_FLAG_R | ETH_DMA_IT_RBU ) ) != 0 ) 432 { 433 /* Receive complete callback */ 434 HAL_ETH_RxCpltCallback( heth ); 435 } 436 437 /* Frame transmitted */ 438 if( ( dmasr & ( ETH_DMA_FLAG_T ) ) != 0 ) 439 { 440 /* Transfer complete callback */ 441 HAL_ETH_TxCpltCallback( heth ); 442 } 443 444 /* ETH DMA Error */ 445 if( ( dmasr & ( ETH_DMA_FLAG_AIS ) ) != 0 ) 446 { 447 /* Ethernet Error callback */ 448 HAL_ETH_ErrorCallback( heth ); 449 } 450 } 451 452 /** 453 * @brief Tx Transfer completed callbacks. 454 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 455 * the configuration information for ETHERNET module 456 * @retval None 457 */ HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth)458 __weak void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef * heth ) 459 { 460 /* NOTE : This function Should not be modified, when the callback is needed, 461 * the HAL_ETH_TxCpltCallback could be implemented in the user file 462 */ 463 ( void ) heth; 464 } 465 466 /** 467 * @brief Rx Transfer completed callbacks. 468 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 469 * the configuration information for ETHERNET module 470 * @retval None 471 */ HAL_ETH_RxCpltCallback(ETH_HandleTypeDef * heth)472 __weak void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef * heth ) 473 { 474 /* NOTE : This function Should not be modified, when the callback is needed, 475 * the HAL_ETH_TxCpltCallback could be implemented in the user file 476 */ 477 ( void ) heth; 478 } 479 480 /** 481 * @brief Ethernet transfer error callbacks 482 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 483 * the configuration information for ETHERNET module 484 * @retval None 485 */ HAL_ETH_ErrorCallback(ETH_HandleTypeDef * heth)486 __weak void HAL_ETH_ErrorCallback( ETH_HandleTypeDef * heth ) 487 { 488 /* NOTE : This function Should not be modified, when the callback is needed, 489 * the HAL_ETH_TxCpltCallback could be implemented in the user file 490 */ 491 ( void ) heth; 492 } 493 494 /** 495 * @brief Reads a PHY register 496 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 497 * the configuration information for ETHERNET module 498 * @param PHYReg: PHY register address, is the index of one of the 32 PHY register. 499 * This parameter can be one of the following values: 500 * PHY_BCR: Transceiver Basic Control Register, 501 * PHY_BSR: Transceiver Basic Status Register. 502 * More PHY register could be read depending on the used PHY 503 * @param RegValue: PHY register value 504 * @retval HAL status 505 */ HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef * heth,uint16_t PHYReg,uint32_t * RegValue)506 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister( ETH_HandleTypeDef * heth, 507 uint16_t PHYReg, 508 uint32_t * RegValue ) 509 { 510 uint32_t tmpreg = 0uL; 511 uint32_t tickstart = 0uL; 512 HAL_StatusTypeDef xResult; 513 514 /* Check parameters */ 515 assert_param( IS_ETH_PHY_ADDRESS( heth->Init.PhyAddress ) ); 516 517 /* Check the ETH peripheral state */ 518 if( heth->State == HAL_ETH_STATE_BUSY_RD ) 519 { 520 xResult = HAL_BUSY; 521 } 522 else 523 { 524 __HAL_LOCK( heth ); 525 526 /* Set ETH HAL State to BUSY_RD */ 527 heth->State = HAL_ETH_STATE_BUSY_RD; 528 529 /* Get the ETHERNET MACMIIAR value */ 530 tmpreg = heth->Instance->MACMIIAR; 531 532 /* Keep only the CSR Clock Range CR[2:0] bits value */ 533 tmpreg &= ~ETH_MACMIIAR_CR_MASK; 534 535 /* Prepare the MII address register value */ 536 tmpreg |= ( ( ( uint32_t ) heth->Init.PhyAddress << 11 ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */ 537 tmpreg |= ( ( ( uint32_t ) PHYReg << 6 ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */ 538 tmpreg &= ~ETH_MACMIIAR_MW; /* Set the read mode */ 539 tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ 540 541 /* Write the result value into the MII Address register */ 542 heth->Instance->MACMIIAR = tmpreg; 543 544 /* Get tick */ 545 tickstart = HAL_GetTick(); 546 547 /* Check for the Busy flag */ 548 while( 1 ) 549 { 550 tmpreg = heth->Instance->MACMIIAR; 551 552 if( ( tmpreg & ETH_MACMIIAR_MB ) == 0uL ) 553 { 554 /* Get MACMIIDR value */ 555 *RegValue = ( uint32_t ) heth->Instance->MACMIIDR; 556 xResult = HAL_OK; 557 break; 558 } 559 560 /* Check for the Timeout */ 561 if( ( HAL_GetTick() - tickstart ) > PHY_READ_TO ) 562 { 563 xResult = HAL_TIMEOUT; 564 break; 565 } 566 } 567 568 /* Set ETH HAL State to READY */ 569 heth->State = HAL_ETH_STATE_READY; 570 571 /* Process Unlocked */ 572 __HAL_UNLOCK( heth ); 573 } 574 575 /* Return function status */ 576 return xResult; 577 } 578 579 /** 580 * @brief Writes to a PHY register. 581 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 582 * the configuration information for ETHERNET module 583 * @param PHYReg: PHY register address, is the index of one of the 32 PHY register. 584 * This parameter can be one of the following values: 585 * PHY_BCR: Transceiver Control Register. 586 * More PHY register could be written depending on the used PHY 587 * @param RegValue: the value to write 588 * @retval HAL status 589 */ HAL_ETH_WritePHYRegister(ETH_HandleTypeDef * heth,uint16_t PHYReg,uint32_t RegValue)590 HAL_StatusTypeDef HAL_ETH_WritePHYRegister( ETH_HandleTypeDef * heth, 591 uint16_t PHYReg, 592 uint32_t RegValue ) 593 { 594 uint32_t tmpreg = 0; 595 uint32_t tickstart = 0; 596 HAL_StatusTypeDef xResult; 597 598 /* Check parameters */ 599 assert_param( IS_ETH_PHY_ADDRESS( heth->Init.PhyAddress ) ); 600 601 /* Check the ETH peripheral state */ 602 if( heth->State == HAL_ETH_STATE_BUSY_WR ) 603 { 604 xResult = HAL_BUSY; 605 } 606 else 607 { 608 __HAL_LOCK( heth ); 609 610 /* Set ETH HAL State to BUSY_WR */ 611 heth->State = HAL_ETH_STATE_BUSY_WR; 612 613 /* Get the ETHERNET MACMIIAR value */ 614 tmpreg = heth->Instance->MACMIIAR; 615 616 /* Keep only the CSR Clock Range CR[2:0] bits value */ 617 tmpreg &= ~ETH_MACMIIAR_CR_MASK; 618 619 /* Prepare the MII register address value */ 620 tmpreg |= ( ( ( uint32_t ) heth->Init.PhyAddress << 11 ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */ 621 tmpreg |= ( ( ( uint32_t ) PHYReg << 6 ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */ 622 tmpreg |= ETH_MACMIIAR_MW; /* Set the write mode */ 623 tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ 624 625 /* Give the value to the MII data register */ 626 heth->Instance->MACMIIDR = ( uint16_t ) RegValue; 627 628 /* Write the result value into the MII Address register */ 629 heth->Instance->MACMIIAR = tmpreg; 630 631 /* Get tick */ 632 tickstart = HAL_GetTick(); 633 634 /* Check for the Busy flag */ 635 while( 1 ) 636 { 637 tmpreg = heth->Instance->MACMIIAR; 638 639 if( ( tmpreg & ETH_MACMIIAR_MB ) == 0ul ) 640 { 641 xResult = HAL_OK; 642 break; 643 } 644 645 /* Check for the Timeout */ 646 if( ( HAL_GetTick() - tickstart ) > PHY_WRITE_TO ) 647 { 648 xResult = HAL_TIMEOUT; 649 break; 650 } 651 } 652 653 /* Set ETH HAL State to READY */ 654 heth->State = HAL_ETH_STATE_READY; 655 /* Process Unlocked */ 656 __HAL_UNLOCK( heth ); 657 } 658 659 /* Return function status */ 660 return xResult; 661 } 662 663 /** 664 * @} 665 */ 666 667 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions 668 * @brief Peripheral Control functions 669 * 670 * @verbatim 671 * =============================================================================== 672 ##### Peripheral Control functions ##### 673 #####=============================================================================== 674 #####[..] This section provides functions allowing to: 675 #####(+) Enable MAC and DMA transmission and reception. 676 ##### HAL_ETH_Start(); 677 #####(+) Disable MAC and DMA transmission and reception. 678 ##### HAL_ETH_Stop(); 679 #####(+) Set the MAC configuration in runtime mode 680 ##### HAL_ETH_ConfigMAC(); 681 #####(+) Set the DMA configuration in runtime mode 682 ##### HAL_ETH_ConfigDMA(); 683 ##### 684 #####@endverbatim 685 * @{ 686 */ 687 688 /** 689 * @brief Enables Ethernet MAC and DMA reception/transmission 690 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 691 * the configuration information for ETHERNET module 692 * @retval HAL status 693 */ HAL_ETH_Start(ETH_HandleTypeDef * heth)694 HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef * heth ) 695 { 696 /* Process Locked */ 697 __HAL_LOCK( heth ); 698 699 /* Set the ETH peripheral state to BUSY */ 700 heth->State = HAL_ETH_STATE_BUSY; 701 702 /* Enable transmit state machine of the MAC for transmission on the MII */ 703 ETH_MACTransmissionEnable( heth ); 704 705 /* Enable receive state machine of the MAC for reception from the MII */ 706 ETH_MACReceptionEnable( heth ); 707 708 /* Flush Transmit FIFO */ 709 ETH_FlushTransmitFIFO( heth ); 710 711 /* Start DMA transmission */ 712 ETH_DMATransmissionEnable( heth ); 713 714 /* Start DMA reception */ 715 ETH_DMAReceptionEnable( heth ); 716 717 /* Set the ETH state to READY*/ 718 heth->State = HAL_ETH_STATE_READY; 719 720 /* Process Unlocked */ 721 __HAL_UNLOCK( heth ); 722 723 /* Return function status */ 724 return HAL_OK; 725 } 726 727 /** 728 * @brief Stop Ethernet MAC and DMA reception/transmission 729 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 730 * the configuration information for ETHERNET module 731 * @retval HAL status 732 */ HAL_ETH_Stop(ETH_HandleTypeDef * heth)733 HAL_StatusTypeDef HAL_ETH_Stop( ETH_HandleTypeDef * heth ) 734 { 735 /* Process Locked */ 736 __HAL_LOCK( heth ); 737 738 /* Set the ETH peripheral state to BUSY */ 739 heth->State = HAL_ETH_STATE_BUSY; 740 741 /* Stop DMA transmission */ 742 ETH_DMATransmissionDisable( heth ); 743 744 /* Stop DMA reception */ 745 ETH_DMAReceptionDisable( heth ); 746 747 /* Disable receive state machine of the MAC for reception from the MII */ 748 ETH_MACReceptionDisable( heth ); 749 750 /* Flush Transmit FIFO */ 751 ETH_FlushTransmitFIFO( heth ); 752 753 /* Disable transmit state machine of the MAC for transmission on the MII */ 754 ETH_MACTransmissionDisable( heth ); 755 756 /* Set the ETH state*/ 757 heth->State = HAL_ETH_STATE_READY; 758 759 /* Process Unlocked */ 760 __HAL_UNLOCK( heth ); 761 762 /* Return function status */ 763 return HAL_OK; 764 } 765 vRegisterDelay()766 static void vRegisterDelay() 767 { 768 uint32_t uxCount; 769 770 /* 771 * Regarding the HAL delay functions, I noticed that HAL delay is being used to workaround the 772 * "Successive write operations to the same register might not be fully taken into account" errata. 773 * The workaround requires a delay of four TX_CLK/RX_CLK clock cycles. For a 10 Mbit connection, 774 * these clocks are running at 2.5 MHz, so this delay would be at most 1.6 microseconds. 775 * 180 Mhz = 288 loops 776 * 168 Mhz = 269 loops 777 * 100 Mhz = 160 loops 778 * 84 Mhz = 134 loops 779 */ 780 #define WAIT_TIME_NS 1600uL /* 1.6 microseconds */ 781 #define CPU_MAX_FREQ SystemCoreClock /* 84, 100, 168 or 180 MHz */ 782 uint32_t NOP_COUNT = ( WAIT_TIME_NS * ( CPU_MAX_FREQ / 1000uL ) ) / 1000000uL; 783 784 for( uxCount = NOP_COUNT; uxCount > 0uL; uxCount-- ) 785 { 786 __NOP(); 787 } 788 } 789 prvWriteMACFCR(ETH_HandleTypeDef * heth,uint32_t ulValue)790 static void prvWriteMACFCR( ETH_HandleTypeDef * heth, 791 uint32_t ulValue ) 792 { 793 /* Enable the MAC transmission */ 794 heth->Instance->MACFCR = ulValue; 795 796 /* Wait until the write operation will be taken into account: 797 * at least four TX_CLK/RX_CLK clock cycles. 798 * Read it back, wait a ms and */ 799 ( void ) heth->Instance->MACFCR; 800 801 vRegisterDelay(); 802 803 heth->Instance->MACFCR = ulValue; 804 } 805 prvWriteDMAOMR(ETH_HandleTypeDef * heth,uint32_t ulValue)806 static void prvWriteDMAOMR( ETH_HandleTypeDef * heth, 807 uint32_t ulValue ) 808 { 809 /* Enable the MAC transmission */ 810 heth->Instance->DMAOMR = ulValue; 811 812 /* Wait until the write operation will be taken into account: 813 * at least four TX_CLK/RX_CLK clock cycles. 814 * Read it back, wait a ms and */ 815 ( void ) heth->Instance->DMAOMR; 816 817 vRegisterDelay(); 818 819 heth->Instance->DMAOMR = ulValue; 820 } 821 prvWriteMACCR(ETH_HandleTypeDef * heth,uint32_t ulValue)822 static void prvWriteMACCR( ETH_HandleTypeDef * heth, 823 uint32_t ulValue ) 824 { 825 /* Enable the MAC transmission */ 826 heth->Instance->MACCR = ulValue; 827 828 /* Wait until the write operation will be taken into account: 829 * at least four TX_CLK/RX_CLK clock cycles. 830 * Read it back, wait a ms and */ 831 ( void ) heth->Instance->MACCR; 832 833 vRegisterDelay(); 834 835 heth->Instance->MACCR = ulValue; 836 } 837 838 /** 839 * @brief Set ETH MAC Configuration. 840 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 841 * the configuration information for ETHERNET module 842 * @param macconf: MAC Configuration structure 843 * @retval HAL status 844 */ HAL_ETH_ConfigMAC(ETH_HandleTypeDef * heth,ETH_MACInitTypeDef * macconf)845 HAL_StatusTypeDef HAL_ETH_ConfigMAC( ETH_HandleTypeDef * heth, 846 ETH_MACInitTypeDef * macconf ) 847 { 848 uint32_t tmpreg = 0uL; 849 850 /* Process Locked */ 851 __HAL_LOCK( heth ); 852 853 /* Set the ETH peripheral state to BUSY */ 854 heth->State = HAL_ETH_STATE_BUSY; 855 856 assert_param( IS_ETH_SPEED( heth->Init.Speed ) ); 857 assert_param( IS_ETH_DUPLEX_MODE( heth->Init.DuplexMode ) ); 858 859 if( macconf != NULL ) 860 { 861 /* Check the parameters */ 862 assert_param( IS_ETH_WATCHDOG( macconf->Watchdog ) ); 863 assert_param( IS_ETH_JABBER( macconf->Jabber ) ); 864 assert_param( IS_ETH_INTER_FRAME_GAP( macconf->InterFrameGap ) ); 865 assert_param( IS_ETH_CARRIER_SENSE( macconf->CarrierSense ) ); 866 assert_param( IS_ETH_RECEIVE_OWN( macconf->ReceiveOwn ) ); 867 assert_param( IS_ETH_LOOPBACK_MODE( macconf->LoopbackMode ) ); 868 assert_param( IS_ETH_CHECKSUM_OFFLOAD( macconf->ChecksumOffload ) ); 869 assert_param( IS_ETH_RETRY_TRANSMISSION( macconf->RetryTransmission ) ); 870 assert_param( IS_ETH_AUTOMATIC_PADCRC_STRIP( macconf->AutomaticPadCRCStrip ) ); 871 assert_param( IS_ETH_BACKOFF_LIMIT( macconf->BackOffLimit ) ); 872 assert_param( IS_ETH_DEFERRAL_CHECK( macconf->DeferralCheck ) ); 873 assert_param( IS_ETH_RECEIVE_ALL( macconf->ReceiveAll ) ); 874 assert_param( IS_ETH_SOURCE_ADDR_FILTER( macconf->SourceAddrFilter ) ); 875 assert_param( IS_ETH_CONTROL_FRAMES( macconf->PassControlFrames ) ); 876 assert_param( IS_ETH_BROADCAST_FRAMES_RECEPTION( macconf->BroadcastFramesReception ) ); 877 assert_param( IS_ETH_DESTINATION_ADDR_FILTER( macconf->DestinationAddrFilter ) ); 878 assert_param( IS_ETH_PROMISCUOUS_MODE( macconf->PromiscuousMode ) ); 879 assert_param( IS_ETH_MULTICAST_FRAMES_FILTER( macconf->MulticastFramesFilter ) ); 880 assert_param( IS_ETH_UNICAST_FRAMES_FILTER( macconf->UnicastFramesFilter ) ); 881 assert_param( IS_ETH_PAUSE_TIME( macconf->PauseTime ) ); 882 assert_param( IS_ETH_ZEROQUANTA_PAUSE( macconf->ZeroQuantaPause ) ); 883 assert_param( IS_ETH_PAUSE_LOW_THRESHOLD( macconf->PauseLowThreshold ) ); 884 assert_param( IS_ETH_UNICAST_PAUSE_FRAME_DETECT( macconf->UnicastPauseFrameDetect ) ); 885 assert_param( IS_ETH_RECEIVE_FLOWCONTROL( macconf->ReceiveFlowControl ) ); 886 assert_param( IS_ETH_TRANSMIT_FLOWCONTROL( macconf->TransmitFlowControl ) ); 887 assert_param( IS_ETH_VLAN_TAG_COMPARISON( macconf->VLANTagComparison ) ); 888 assert_param( IS_ETH_VLAN_TAG_IDENTIFIER( macconf->VLANTagIdentifier ) ); 889 890 /*------------------------ ETHERNET MACCR Configuration --------------------*/ 891 /* Get the ETHERNET MACCR value */ 892 tmpreg = heth->Instance->MACCR; 893 /* Clear WD, PCE, PS, TE and RE bits */ 894 tmpreg &= ETH_MACCR_CLEAR_MASK; 895 896 tmpreg |= ( uint32_t ) ( 897 macconf->Watchdog | 898 macconf->Jabber | 899 macconf->InterFrameGap | 900 macconf->CarrierSense | 901 heth->Init.Speed | 902 macconf->ReceiveOwn | 903 macconf->LoopbackMode | 904 heth->Init.DuplexMode | 905 macconf->ChecksumOffload | 906 macconf->RetryTransmission | 907 macconf->AutomaticPadCRCStrip | 908 macconf->BackOffLimit | 909 macconf->DeferralCheck ); 910 911 /* Write to ETHERNET MACCR */ 912 prvWriteMACCR( heth, tmpreg ); 913 914 /*----------------------- ETHERNET MACFFR Configuration --------------------*/ 915 /* Write to ETHERNET MACFFR */ 916 heth->Instance->MACFFR = ( uint32_t ) ( 917 macconf->ReceiveAll | 918 macconf->SourceAddrFilter | 919 macconf->PassControlFrames | 920 macconf->BroadcastFramesReception | 921 macconf->DestinationAddrFilter | 922 macconf->PromiscuousMode | 923 macconf->MulticastFramesFilter | 924 macconf->UnicastFramesFilter ); 925 926 /* Wait until the write operation will be taken into account : 927 * at least four TX_CLK/RX_CLK clock cycles */ 928 tmpreg = heth->Instance->MACFFR; 929 vRegisterDelay(); 930 heth->Instance->MACFFR = tmpreg; 931 932 /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/ 933 /* Write to ETHERNET MACHTHR */ 934 heth->Instance->MACHTHR = ( uint32_t ) macconf->HashTableHigh; 935 936 /* Write to ETHERNET MACHTLR */ 937 heth->Instance->MACHTLR = ( uint32_t ) macconf->HashTableLow; 938 /*----------------------- ETHERNET MACFCR Configuration --------------------*/ 939 940 /* Get the ETHERNET MACFCR value */ 941 tmpreg = heth->Instance->MACFCR; 942 /* Clear xx bits */ 943 tmpreg &= ETH_MACFCR_CLEAR_MASK; 944 945 tmpreg |= ( uint32_t ) ( ( 946 macconf->PauseTime << 16 ) | 947 macconf->ZeroQuantaPause | 948 macconf->PauseLowThreshold | 949 macconf->UnicastPauseFrameDetect | 950 macconf->ReceiveFlowControl | 951 macconf->TransmitFlowControl ); 952 953 /* Write to ETHERNET MACFCR */ 954 prvWriteMACFCR( heth, tmpreg ); 955 956 /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/ 957 heth->Instance->MACVLANTR = ( uint32_t ) ( macconf->VLANTagComparison | 958 macconf->VLANTagIdentifier ); 959 960 /* Wait until the write operation will be taken into account : 961 * at least four TX_CLK/RX_CLK clock cycles */ 962 tmpreg = heth->Instance->MACVLANTR; 963 vRegisterDelay(); 964 heth->Instance->MACVLANTR = tmpreg; 965 } 966 else /* macconf == NULL : here we just configure Speed and Duplex mode */ 967 { 968 /*------------------------ ETHERNET MACCR Configuration --------------------*/ 969 /* Get the ETHERNET MACCR value */ 970 tmpreg = heth->Instance->MACCR; 971 972 /* Clear FES and DM bits */ 973 tmpreg &= ~( ( uint32_t ) 0x00004800uL ); 974 975 tmpreg |= ( uint32_t ) ( heth->Init.Speed | heth->Init.DuplexMode ); 976 977 /* Write to ETHERNET MACCR */ 978 prvWriteMACCR( heth, tmpreg ); 979 } 980 981 /* Set the ETH state to Ready */ 982 heth->State = HAL_ETH_STATE_READY; 983 984 /* Process Unlocked */ 985 __HAL_UNLOCK( heth ); 986 987 /* Return function status */ 988 return HAL_OK; 989 } 990 991 /** 992 * @brief Sets ETH DMA Configuration. 993 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 994 * the configuration information for ETHERNET module 995 * @param dmaconf: DMA Configuration structure 996 * @retval HAL status 997 */ HAL_ETH_ConfigDMA(ETH_HandleTypeDef * heth,ETH_DMAInitTypeDef * dmaconf)998 HAL_StatusTypeDef HAL_ETH_ConfigDMA( ETH_HandleTypeDef * heth, 999 ETH_DMAInitTypeDef * dmaconf ) 1000 { 1001 uint32_t tmpreg = 0uL; 1002 1003 /* Process Locked */ 1004 __HAL_LOCK( heth ); 1005 1006 /* Set the ETH peripheral state to BUSY */ 1007 heth->State = HAL_ETH_STATE_BUSY; 1008 1009 /* Check parameters */ 1010 assert_param( IS_ETH_DROP_TCPIP_CHECKSUM_FRAME( dmaconf->DropTCPIPChecksumErrorFrame ) ); 1011 assert_param( IS_ETH_RECEIVE_STORE_FORWARD( dmaconf->ReceiveStoreForward ) ); 1012 assert_param( IS_ETH_FLUSH_RECEIVE_FRAME( dmaconf->FlushReceivedFrame ) ); 1013 assert_param( IS_ETH_TRANSMIT_STORE_FORWARD( dmaconf->TransmitStoreForward ) ); 1014 assert_param( IS_ETH_TRANSMIT_THRESHOLD_CONTROL( dmaconf->TransmitThresholdControl ) ); 1015 assert_param( IS_ETH_FORWARD_ERROR_FRAMES( dmaconf->ForwardErrorFrames ) ); 1016 assert_param( IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES( dmaconf->ForwardUndersizedGoodFrames ) ); 1017 assert_param( IS_ETH_RECEIVE_THRESHOLD_CONTROL( dmaconf->ReceiveThresholdControl ) ); 1018 assert_param( IS_ETH_SECOND_FRAME_OPERATE( dmaconf->SecondFrameOperate ) ); 1019 assert_param( IS_ETH_ADDRESS_ALIGNED_BEATS( dmaconf->AddressAlignedBeats ) ); 1020 assert_param( IS_ETH_FIXED_BURST( dmaconf->FixedBurst ) ); 1021 assert_param( IS_ETH_RXDMA_BURST_LENGTH( dmaconf->RxDMABurstLength ) ); 1022 assert_param( IS_ETH_TXDMA_BURST_LENGTH( dmaconf->TxDMABurstLength ) ); 1023 assert_param( IS_ETH_ENHANCED_DESCRIPTOR_FORMAT( dmaconf->EnhancedDescriptorFormat ) ); 1024 assert_param( IS_ETH_DMA_DESC_SKIP_LENGTH( dmaconf->DescriptorSkipLength ) ); 1025 assert_param( IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX( dmaconf->DMAArbitration ) ); 1026 1027 /*----------------------- ETHERNET DMAOMR Configuration --------------------*/ 1028 /* Get the ETHERNET DMAOMR value */ 1029 tmpreg = heth->Instance->DMAOMR; 1030 /* Clear xx bits */ 1031 tmpreg &= ETH_DMAOMR_CLEAR_MASK; 1032 1033 tmpreg |= ( uint32_t ) ( 1034 dmaconf->DropTCPIPChecksumErrorFrame | 1035 dmaconf->ReceiveStoreForward | 1036 dmaconf->FlushReceivedFrame | 1037 dmaconf->TransmitStoreForward | 1038 dmaconf->TransmitThresholdControl | 1039 dmaconf->ForwardErrorFrames | 1040 dmaconf->ForwardUndersizedGoodFrames | 1041 dmaconf->ReceiveThresholdControl | 1042 dmaconf->SecondFrameOperate ); 1043 1044 /* Write to ETHERNET DMAOMR */ 1045 prvWriteDMAOMR( heth, tmpreg ); 1046 1047 /*----------------------- ETHERNET DMABMR Configuration --------------------*/ 1048 heth->Instance->DMABMR = ( uint32_t ) ( dmaconf->AddressAlignedBeats | 1049 dmaconf->FixedBurst | 1050 dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ 1051 dmaconf->TxDMABurstLength | 1052 dmaconf->EnhancedDescriptorFormat | 1053 ( dmaconf->DescriptorSkipLength << 2 ) | 1054 dmaconf->DMAArbitration | 1055 ETH_DMABMR_USP ); /* Enable use of separate PBL for Rx and Tx */ 1056 1057 /* Wait until the write operation will be taken into account: 1058 * at least four TX_CLK/RX_CLK clock cycles */ 1059 tmpreg = heth->Instance->DMABMR; 1060 vRegisterDelay(); 1061 heth->Instance->DMABMR = tmpreg; 1062 1063 /* Set the ETH state to Ready */ 1064 heth->State = HAL_ETH_STATE_READY; 1065 1066 /* Process Unlocked */ 1067 __HAL_UNLOCK( heth ); 1068 1069 /* Return function status */ 1070 return HAL_OK; 1071 } 1072 1073 /** 1074 * @} 1075 */ 1076 1077 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions 1078 * @brief Peripheral State functions 1079 * 1080 * @verbatim 1081 * =============================================================================== 1082 ##### Peripheral State functions ##### 1083 #####=============================================================================== 1084 #####[..] 1085 #####This subsection permits to get in run-time the status of the peripheral 1086 #####and the data flow. 1087 ##### (+) Get the ETH handle state: 1088 ##### HAL_ETH_GetState(); 1089 ##### 1090 ##### 1091 #####@endverbatim 1092 * @{ 1093 */ 1094 1095 /** 1096 * @brief Return the ETH HAL state 1097 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1098 * the configuration information for ETHERNET module 1099 * @retval HAL state 1100 */ HAL_ETH_GetState(ETH_HandleTypeDef * heth)1101 HAL_ETH_StateTypeDef HAL_ETH_GetState( ETH_HandleTypeDef * heth ) 1102 { 1103 /* Return ETH state */ 1104 return heth->State; 1105 } 1106 1107 /** 1108 * @} 1109 */ 1110 1111 /** 1112 * @} 1113 */ 1114 1115 /** @addtogroup ETH_Private_Functions 1116 * @{ 1117 */ 1118 1119 /** 1120 * @brief Configures Ethernet MAC and DMA with default parameters. 1121 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1122 * the configuration information for ETHERNET module 1123 * @param err: Ethernet Init error 1124 * @retval HAL status 1125 */ ETH_MACDMAConfig(ETH_HandleTypeDef * heth,uint32_t err)1126 static void ETH_MACDMAConfig( ETH_HandleTypeDef * heth, 1127 uint32_t err ) 1128 { 1129 ETH_MACInitTypeDef macinit; 1130 ETH_DMAInitTypeDef dmainit; 1131 uint32_t tmpreg = 0uL; 1132 1133 if( err != ETH_SUCCESS ) /* Auto-negotiation failed */ 1134 { 1135 /* Set Ethernet duplex mode to Full-duplex */ 1136 heth->Init.DuplexMode = ETH_MODE_FULLDUPLEX; 1137 1138 /* Set Ethernet speed to 100M */ 1139 heth->Init.Speed = ETH_SPEED_100M; 1140 } 1141 1142 /* Ethernet MAC default initialization **************************************/ 1143 macinit.Watchdog = ETH_WATCHDOG_ENABLE; 1144 macinit.Jabber = ETH_JABBER_ENABLE; 1145 macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT; 1146 macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE; 1147 macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE; 1148 macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE; 1149 1150 if( heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE ) 1151 { 1152 macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE; 1153 } 1154 else 1155 { 1156 macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE; 1157 } 1158 1159 macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE; 1160 macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE; 1161 macinit.BackOffLimit = ETH_BACKOFFLIMIT_10; 1162 macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE; 1163 macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; 1164 macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE; 1165 macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL; 1166 macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE; 1167 macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; 1168 macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; 1169 macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; 1170 macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; 1171 macinit.HashTableHigh = 0x0uL; 1172 macinit.HashTableLow = 0x0uL; 1173 macinit.PauseTime = 0x0uL; 1174 macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE; 1175 macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4; 1176 macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE; 1177 macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; 1178 macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; 1179 macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT; 1180 macinit.VLANTagIdentifier = 0x0uL; 1181 1182 /*------------------------ ETHERNET MACCR Configuration --------------------*/ 1183 /* Get the ETHERNET MACCR value */ 1184 tmpreg = heth->Instance->MACCR; 1185 /* Clear WD, PCE, PS, TE and RE bits */ 1186 tmpreg &= ETH_MACCR_CLEAR_MASK; 1187 /* Set the WD bit according to ETH Watchdog value */ 1188 /* Set the JD: bit according to ETH Jabber value */ 1189 /* Set the IFG bit according to ETH InterFrameGap value */ 1190 /* Set the DCRS bit according to ETH CarrierSense value */ 1191 /* Set the FES bit according to ETH Speed value */ 1192 /* Set the DO bit according to ETH ReceiveOwn value */ 1193 /* Set the LM bit according to ETH LoopbackMode value */ 1194 /* Set the DM bit according to ETH Mode value */ 1195 /* Set the IPCO bit according to ETH ChecksumOffload value */ 1196 /* Set the DR bit according to ETH RetryTransmission value */ 1197 /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */ 1198 /* Set the BL bit according to ETH BackOffLimit value */ 1199 /* Set the DC bit according to ETH DeferralCheck value */ 1200 tmpreg |= ( uint32_t ) ( macinit.Watchdog | 1201 macinit.Jabber | 1202 macinit.InterFrameGap | 1203 macinit.CarrierSense | 1204 heth->Init.Speed | 1205 macinit.ReceiveOwn | 1206 macinit.LoopbackMode | 1207 heth->Init.DuplexMode | 1208 macinit.ChecksumOffload | 1209 macinit.RetryTransmission | 1210 macinit.AutomaticPadCRCStrip | 1211 macinit.BackOffLimit | 1212 macinit.DeferralCheck ); 1213 1214 /* Write to ETHERNET MACCR */ 1215 prvWriteMACCR( heth, tmpreg ); 1216 1217 /*----------------------- ETHERNET MACFFR Configuration --------------------*/ 1218 /* Set the RA bit according to ETH ReceiveAll value */ 1219 /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */ 1220 /* Set the PCF bit according to ETH PassControlFrames value */ 1221 /* Set the DBF bit according to ETH BroadcastFramesReception value */ 1222 /* Set the DAIF bit according to ETH DestinationAddrFilter value */ 1223 /* Set the PR bit according to ETH PromiscuousMode value */ 1224 /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */ 1225 /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */ 1226 /* Write to ETHERNET MACFFR */ 1227 heth->Instance->MACFFR = ( uint32_t ) ( macinit.ReceiveAll | 1228 macinit.SourceAddrFilter | 1229 macinit.PassControlFrames | 1230 macinit.BroadcastFramesReception | 1231 macinit.DestinationAddrFilter | 1232 macinit.PromiscuousMode | 1233 macinit.MulticastFramesFilter | 1234 macinit.UnicastFramesFilter ); 1235 1236 /* Wait until the write operation will be taken into account: 1237 * at least four TX_CLK/RX_CLK clock cycles */ 1238 tmpreg = heth->Instance->MACFFR; 1239 vRegisterDelay(); 1240 heth->Instance->MACFFR = tmpreg; 1241 1242 /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/ 1243 /* Write to ETHERNET MACHTHR */ 1244 heth->Instance->MACHTHR = ( uint32_t ) macinit.HashTableHigh; 1245 1246 /* Write to ETHERNET MACHTLR */ 1247 heth->Instance->MACHTLR = ( uint32_t ) macinit.HashTableLow; 1248 /*----------------------- ETHERNET MACFCR Configuration -------------------*/ 1249 1250 /* Get the ETHERNET MACFCR value */ 1251 tmpreg = heth->Instance->MACFCR; 1252 /* Clear xx bits */ 1253 tmpreg &= ETH_MACFCR_CLEAR_MASK; 1254 1255 /* Set the PT bit according to ETH PauseTime value */ 1256 /* Set the DZPQ bit according to ETH ZeroQuantaPause value */ 1257 /* Set the PLT bit according to ETH PauseLowThreshold value */ 1258 /* Set the UP bit according to ETH UnicastPauseFrameDetect value */ 1259 /* Set the RFE bit according to ETH ReceiveFlowControl value */ 1260 /* Set the TFE bit according to ETH TransmitFlowControl value */ 1261 tmpreg |= ( uint32_t ) ( ( macinit.PauseTime << 16 ) | 1262 macinit.ZeroQuantaPause | 1263 macinit.PauseLowThreshold | 1264 macinit.UnicastPauseFrameDetect | 1265 macinit.ReceiveFlowControl | 1266 macinit.TransmitFlowControl ); 1267 1268 /* Write to ETHERNET MACFCR */ 1269 prvWriteMACFCR( heth, tmpreg ); 1270 1271 /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/ 1272 /* Set the ETV bit according to ETH VLANTagComparison value */ 1273 /* Set the VL bit according to ETH VLANTagIdentifier value */ 1274 heth->Instance->MACVLANTR = ( uint32_t ) ( macinit.VLANTagComparison | 1275 macinit.VLANTagIdentifier ); 1276 1277 /* Wait until the write operation will be taken into account: 1278 * at least four TX_CLK/RX_CLK clock cycles */ 1279 tmpreg = heth->Instance->MACVLANTR; 1280 vRegisterDelay(); 1281 heth->Instance->MACVLANTR = tmpreg; 1282 1283 /* Ethernet DMA default initialization ************************************/ 1284 dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE; 1285 dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE; 1286 dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE; 1287 dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE; 1288 dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES; 1289 dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE; 1290 dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE; 1291 dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES; 1292 dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE; 1293 dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE; 1294 dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE; 1295 dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; 1296 dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; 1297 dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE; 1298 dmainit.DescriptorSkipLength = 0x0uL; 1299 dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1; 1300 1301 /* Get the ETHERNET DMAOMR value */ 1302 tmpreg = heth->Instance->DMAOMR; 1303 /* Clear xx bits */ 1304 tmpreg &= ETH_DMAOMR_CLEAR_MASK; 1305 1306 /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */ 1307 /* Set the RSF bit according to ETH ReceiveStoreForward value */ 1308 /* Set the DFF bit according to ETH FlushReceivedFrame value */ 1309 /* Set the TSF bit according to ETH TransmitStoreForward value */ 1310 /* Set the TTC bit according to ETH TransmitThresholdControl value */ 1311 /* Set the FEF bit according to ETH ForwardErrorFrames value */ 1312 /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */ 1313 /* Set the RTC bit according to ETH ReceiveThresholdControl value */ 1314 /* Set the OSF bit according to ETH SecondFrameOperate value */ 1315 tmpreg |= ( uint32_t ) ( dmainit.DropTCPIPChecksumErrorFrame | 1316 dmainit.ReceiveStoreForward | 1317 dmainit.FlushReceivedFrame | 1318 dmainit.TransmitStoreForward | 1319 dmainit.TransmitThresholdControl | 1320 dmainit.ForwardErrorFrames | 1321 dmainit.ForwardUndersizedGoodFrames | 1322 dmainit.ReceiveThresholdControl | 1323 dmainit.SecondFrameOperate ); 1324 1325 /* Write to ETHERNET DMAOMR */ 1326 prvWriteDMAOMR( heth, tmpreg ); 1327 1328 /*----------------------- ETHERNET DMABMR Configuration ------------------*/ 1329 /* Set the AAL bit according to ETH AddressAlignedBeats value */ 1330 /* Set the FB bit according to ETH FixedBurst value */ 1331 /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */ 1332 /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */ 1333 /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/ 1334 /* Set the DSL bit according to ETH DesciptorSkipLength value */ 1335 /* Set the PR and DA bits according to ETH DMAArbitration value */ 1336 heth->Instance->DMABMR = ( uint32_t ) ( dmainit.AddressAlignedBeats | 1337 dmainit.FixedBurst | 1338 dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ 1339 dmainit.TxDMABurstLength | 1340 dmainit.EnhancedDescriptorFormat | 1341 ( dmainit.DescriptorSkipLength << 2 ) | 1342 dmainit.DMAArbitration | 1343 ETH_DMABMR_USP ); /* Enable use of separate PBL for Rx and Tx */ 1344 1345 /* Wait until the write operation will be taken into account: 1346 * at least four TX_CLK/RX_CLK clock cycles */ 1347 tmpreg = heth->Instance->DMABMR; 1348 vRegisterDelay(); 1349 heth->Instance->DMABMR = tmpreg; 1350 1351 if( heth->Init.RxMode == ETH_RXINTERRUPT_MODE ) 1352 { 1353 /* Enable the Ethernet Rx Interrupt */ 1354 __HAL_ETH_DMA_ENABLE_IT( ( heth ), ETH_DMA_IT_NIS | ETH_DMA_IT_R ); 1355 } 1356 1357 /* Initialize MAC address in ethernet MAC */ 1358 ETH_MACAddressConfig( heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr ); 1359 } 1360 1361 /** 1362 * @brief Configures the selected MAC address. 1363 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1364 * the configuration information for ETHERNET module 1365 * @param MacAddr: The MAC address to configure 1366 * This parameter can be one of the following values: 1367 * @arg ETH_MAC_Address0: MAC Address0 1368 * @arg ETH_MAC_Address1: MAC Address1 1369 * @arg ETH_MAC_Address2: MAC Address2 1370 * @arg ETH_MAC_Address3: MAC Address3 1371 * @param Addr: Pointer to MAC address buffer data (6 bytes) 1372 * @retval HAL status 1373 */ ETH_MACAddressConfig(ETH_HandleTypeDef * heth,uint32_t MacAddr,uint8_t * Addr)1374 static void ETH_MACAddressConfig( ETH_HandleTypeDef * heth, 1375 uint32_t MacAddr, 1376 uint8_t * Addr ) 1377 { 1378 uint32_t tmpreg; 1379 1380 ( void ) heth; 1381 1382 /* Check the parameters */ 1383 assert_param( IS_ETH_MAC_ADDRESS0123( MacAddr ) ); 1384 1385 /* Calculate the selected MAC address high register */ 1386 /* Register ETH_MACA0HR: Bit 31 MO: Always 1. */ 1387 tmpreg = 0x80000000uL | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ]; 1388 /* Load the selected MAC address high register */ 1389 ( *( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + MacAddr ) ) ) = tmpreg; 1390 /* Calculate the selected MAC address low register */ 1391 tmpreg = ( ( uint32_t ) Addr[ 3 ] << 24 ) | ( ( uint32_t ) Addr[ 2 ] << 16 ) | ( ( uint32_t ) Addr[ 1 ] << 8 ) | Addr[ 0 ]; 1392 1393 /* Load the selected MAC address low register */ 1394 ( *( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + MacAddr ) ) ) = tmpreg; 1395 } 1396 1397 /** 1398 * @brief Enables the MAC transmission. 1399 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1400 * the configuration information for ETHERNET module 1401 * @retval None 1402 */ ETH_MACTransmissionEnable(ETH_HandleTypeDef * heth)1403 static void ETH_MACTransmissionEnable( ETH_HandleTypeDef * heth ) 1404 { 1405 uint32_t tmpreg = heth->Instance->MACCR | ETH_MACCR_TE; 1406 1407 prvWriteMACCR( heth, tmpreg ); 1408 } 1409 1410 /** 1411 * @brief Disables the MAC transmission. 1412 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1413 * the configuration information for ETHERNET module 1414 * @retval None 1415 */ ETH_MACTransmissionDisable(ETH_HandleTypeDef * heth)1416 static void ETH_MACTransmissionDisable( ETH_HandleTypeDef * heth ) 1417 { 1418 uint32_t tmpreg = heth->Instance->MACCR & ~( ETH_MACCR_TE ); 1419 1420 prvWriteMACCR( heth, tmpreg ); 1421 } 1422 1423 /** 1424 * @brief Enables the MAC reception. 1425 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1426 * the configuration information for ETHERNET module 1427 * @retval None 1428 */ ETH_MACReceptionEnable(ETH_HandleTypeDef * heth)1429 static void ETH_MACReceptionEnable( ETH_HandleTypeDef * heth ) 1430 { 1431 __IO uint32_t tmpreg = heth->Instance->MACCR | ETH_MACCR_RE; 1432 1433 prvWriteMACCR( heth, tmpreg ); 1434 } 1435 1436 /** 1437 * @brief Disables the MAC reception. 1438 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1439 * the configuration information for ETHERNET module 1440 * @retval None 1441 */ ETH_MACReceptionDisable(ETH_HandleTypeDef * heth)1442 static void ETH_MACReceptionDisable( ETH_HandleTypeDef * heth ) 1443 { 1444 __IO uint32_t tmpreg = heth->Instance->MACCR & ~( ETH_MACCR_RE ); 1445 1446 prvWriteMACCR( heth, tmpreg ); 1447 } 1448 1449 /** 1450 * @brief Enables the DMA transmission. 1451 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1452 * the configuration information for ETHERNET module 1453 * @retval None 1454 */ ETH_DMATransmissionEnable(ETH_HandleTypeDef * heth)1455 static void ETH_DMATransmissionEnable( ETH_HandleTypeDef * heth ) 1456 { 1457 /* Enable the DMA transmission */ 1458 __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_ST; 1459 1460 prvWriteDMAOMR( heth, tmpreg ); 1461 } 1462 1463 /** 1464 * @brief Disables the DMA transmission. 1465 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1466 * the configuration information for ETHERNET module 1467 * @retval None 1468 */ ETH_DMATransmissionDisable(ETH_HandleTypeDef * heth)1469 static void ETH_DMATransmissionDisable( ETH_HandleTypeDef * heth ) 1470 { 1471 /* Disable the DMA transmission */ 1472 __IO uint32_t tmpreg = heth->Instance->DMAOMR & ~( ETH_DMAOMR_ST ); 1473 1474 prvWriteDMAOMR( heth, tmpreg ); 1475 } 1476 1477 /** 1478 * @brief Enables the DMA reception. 1479 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1480 * the configuration information for ETHERNET module 1481 * @retval None 1482 */ ETH_DMAReceptionEnable(ETH_HandleTypeDef * heth)1483 static void ETH_DMAReceptionEnable( ETH_HandleTypeDef * heth ) 1484 { 1485 /* Enable the DMA reception */ 1486 __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_SR; 1487 1488 prvWriteDMAOMR( heth, tmpreg ); 1489 } 1490 1491 /** 1492 * @brief Disables the DMA reception. 1493 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1494 * the configuration information for ETHERNET module 1495 * @retval None 1496 */ ETH_DMAReceptionDisable(ETH_HandleTypeDef * heth)1497 static void ETH_DMAReceptionDisable( ETH_HandleTypeDef * heth ) 1498 { 1499 /* Disable the DMA reception */ 1500 __IO uint32_t tmpreg = heth->Instance->DMAOMR & ~( ETH_DMAOMR_SR ); 1501 1502 prvWriteDMAOMR( heth, tmpreg ); 1503 } 1504 1505 /** 1506 * @brief Clears the ETHERNET transmit FIFO. 1507 * @param heth: pointer to a ETH_HandleTypeDef structure that contains 1508 * the configuration information for ETHERNET module 1509 * @retval None 1510 */ ETH_FlushTransmitFIFO(ETH_HandleTypeDef * heth)1511 static void ETH_FlushTransmitFIFO( ETH_HandleTypeDef * heth ) 1512 { 1513 /* Set the Flush Transmit FIFO bit */ 1514 __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_FTF; 1515 1516 prvWriteDMAOMR( heth, tmpreg ); 1517 } 1518 1519 /** 1520 * @} 1521 */ 1522 #endif /* stm_is_F1 != 0 || stm_is_F2 != 0 || stm_is_F4 != 0 || stm_is_F7 */ 1523 1524 #endif /* HAL_ETH_MODULE_ENABLED */ 1525 1526 /** 1527 * @} 1528 */ 1529 1530 /** 1531 * @} 1532 */ 1533 1534 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 1535