Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
lan8710.c
00001 /** 00002 * @file lan8710.c 00003 * @brief LAN8710 Ethernet PHY transceiver 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL NIC_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include "core/net.h" 00034 #include "drivers/lan8710.h" 00035 #include "debug.h" 00036 00037 00038 /** 00039 * @brief LAN8710 Ethernet PHY driver 00040 **/ 00041 00042 const PhyDriver lan8710PhyDriver = 00043 { 00044 lan8710Init, 00045 lan8710Tick, 00046 lan8710EnableIrq, 00047 lan8710DisableIrq, 00048 lan8710EventHandler, 00049 }; 00050 00051 00052 /** 00053 * @brief LAN8710 PHY transceiver initialization 00054 * @param[in] interface Underlying network interface 00055 * @return Error code 00056 **/ 00057 00058 error_t lan8710Init(NetInterface *interface) 00059 { 00060 //Debug message 00061 TRACE_INFO("Initializing LAN8710...\r\n"); 00062 00063 //Initialize external interrupt line driver 00064 if(interface->extIntDriver != NULL) 00065 interface->extIntDriver->init(); 00066 00067 //Reset PHY transceiver (soft reset) 00068 lan8710WritePhyReg(interface, LAN8710_PHY_REG_BMCR, BMCR_RESET); 00069 //Wait for the reset to complete 00070 while(lan8710ReadPhyReg(interface, LAN8710_PHY_REG_BMCR) & BMCR_RESET); 00071 00072 //Dump PHY registers for debugging purpose 00073 lan8710DumpPhyReg(interface); 00074 00075 //The PHY will generate interrupts when link status changes are detected 00076 lan8710WritePhyReg(interface, LAN8710_PHY_REG_IMR, IMR_AN_COMPLETE | IMR_LINK_DOWN); 00077 00078 //Force the TCP/IP stack to poll the link state at startup 00079 interface->phyEvent = TRUE; 00080 //Notify the TCP/IP stack of the event 00081 osSetEvent(&netEvent); 00082 00083 //Successful initialization 00084 return NO_ERROR; 00085 } 00086 00087 00088 /** 00089 * @brief LAN8710 timer handler 00090 * @param[in] interface Underlying network interface 00091 **/ 00092 00093 void lan8710Tick(NetInterface *interface) 00094 { 00095 uint16_t value; 00096 bool_t linkState; 00097 00098 //No external interrupt line driver? 00099 if(interface->extIntDriver == NULL) 00100 { 00101 //Read basic status register 00102 value = lan8710ReadPhyReg(interface, LAN8710_PHY_REG_BMSR); 00103 //Retrieve current link state 00104 linkState = (value & BMSR_LINK_STATUS) ? TRUE : FALSE; 00105 00106 //Link up event? 00107 if(linkState && !interface->linkState) 00108 { 00109 //Set event flag 00110 interface->phyEvent = TRUE; 00111 //Notify the TCP/IP stack of the event 00112 osSetEvent(&netEvent); 00113 } 00114 //Link down event? 00115 else if(!linkState && interface->linkState) 00116 { 00117 //Set event flag 00118 interface->phyEvent = TRUE; 00119 //Notify the TCP/IP stack of the event 00120 osSetEvent(&netEvent); 00121 } 00122 } 00123 } 00124 00125 00126 /** 00127 * @brief Enable interrupts 00128 * @param[in] interface Underlying network interface 00129 **/ 00130 00131 void lan8710EnableIrq(NetInterface *interface) 00132 { 00133 //Enable PHY transceiver interrupts 00134 if(interface->extIntDriver != NULL) 00135 interface->extIntDriver->enableIrq(); 00136 } 00137 00138 00139 /** 00140 * @brief Disable interrupts 00141 * @param[in] interface Underlying network interface 00142 **/ 00143 00144 void lan8710DisableIrq(NetInterface *interface) 00145 { 00146 //Disable PHY transceiver interrupts 00147 if(interface->extIntDriver != NULL) 00148 interface->extIntDriver->disableIrq(); 00149 } 00150 00151 00152 /** 00153 * @brief LAN8710 event handler 00154 * @param[in] interface Underlying network interface 00155 **/ 00156 00157 void lan8710EventHandler(NetInterface *interface) 00158 { 00159 uint16_t value; 00160 00161 //Read status register to acknowledge the interrupt 00162 value = lan8710ReadPhyReg(interface, LAN8710_PHY_REG_ISR); 00163 00164 //Link status change? 00165 if(value & (IMR_AN_COMPLETE | IMR_LINK_DOWN)) 00166 { 00167 //Any link failure condition is latched in the BMSR register... Reading 00168 //the register twice will always return the actual link status 00169 value = lan8710ReadPhyReg(interface, LAN8710_PHY_REG_BMSR); 00170 value = lan8710ReadPhyReg(interface, LAN8710_PHY_REG_BMSR); 00171 00172 //Link is up? 00173 if(value & BMSR_LINK_STATUS) 00174 { 00175 //Read PHY special control/status register 00176 value = lan8710ReadPhyReg(interface, LAN8710_PHY_REG_PSCSR); 00177 00178 //Check current operation mode 00179 switch(value & PSCSR_HCDSPEED_MASK) 00180 { 00181 //10BASE-T 00182 case PSCSR_HCDSPEED_10BT: 00183 interface->linkSpeed = NIC_LINK_SPEED_10MBPS; 00184 interface->duplexMode = NIC_HALF_DUPLEX_MODE; 00185 break; 00186 //10BASE-T full-duplex 00187 case PSCSR_HCDSPEED_10BT_FD: 00188 interface->linkSpeed = NIC_LINK_SPEED_10MBPS; 00189 interface->duplexMode = NIC_FULL_DUPLEX_MODE; 00190 break; 00191 //100BASE-TX 00192 case PSCSR_HCDSPEED_100BTX: 00193 interface->linkSpeed = NIC_LINK_SPEED_100MBPS; 00194 interface->duplexMode = NIC_HALF_DUPLEX_MODE; 00195 break; 00196 //100BASE-TX full-duplex 00197 case PSCSR_HCDSPEED_100BTX_FD: 00198 interface->linkSpeed = NIC_LINK_SPEED_100MBPS; 00199 interface->duplexMode = NIC_FULL_DUPLEX_MODE; 00200 break; 00201 //Unknown operation mode 00202 default: 00203 //Debug message 00204 TRACE_WARNING("Invalid Duplex mode\r\n"); 00205 break; 00206 } 00207 00208 //Update link state 00209 interface->linkState = TRUE; 00210 00211 //Adjust MAC configuration parameters for proper operation 00212 interface->nicDriver->updateMacConfig(interface); 00213 } 00214 else 00215 { 00216 //Update link state 00217 interface->linkState = FALSE; 00218 } 00219 00220 //Process link state change event 00221 nicNotifyLinkChange(interface); 00222 } 00223 } 00224 00225 00226 /** 00227 * @brief Write PHY register 00228 * @param[in] interface Underlying network interface 00229 * @param[in] address PHY register address 00230 * @param[in] data Register value 00231 **/ 00232 00233 void lan8710WritePhyReg(NetInterface *interface, uint8_t address, uint16_t data) 00234 { 00235 uint8_t phyAddr; 00236 00237 //Get the address of the PHY transceiver 00238 if(interface->phyAddr < 32) 00239 phyAddr = interface->phyAddr; 00240 else 00241 phyAddr = LAN8710_PHY_ADDR; 00242 00243 //Write the specified PHY register 00244 interface->nicDriver->writePhyReg(phyAddr, address, data); 00245 } 00246 00247 00248 /** 00249 * @brief Read PHY register 00250 * @param[in] interface Underlying network interface 00251 * @param[in] address PHY register address 00252 * @return Register value 00253 **/ 00254 00255 uint16_t lan8710ReadPhyReg(NetInterface *interface, uint8_t address) 00256 { 00257 uint8_t phyAddr; 00258 00259 //Get the address of the PHY transceiver 00260 if(interface->phyAddr < 32) 00261 phyAddr = interface->phyAddr; 00262 else 00263 phyAddr = LAN8710_PHY_ADDR; 00264 00265 //Read the specified PHY register 00266 return interface->nicDriver->readPhyReg(phyAddr, address); 00267 } 00268 00269 00270 /** 00271 * @brief Dump PHY registers for debugging purpose 00272 * @param[in] interface Underlying network interface 00273 **/ 00274 00275 void lan8710DumpPhyReg(NetInterface *interface) 00276 { 00277 uint8_t i; 00278 00279 //Loop through PHY registers 00280 for(i = 0; i < 32; i++) 00281 { 00282 //Display current PHY register 00283 TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i, lan8710ReadPhyReg(interface, i)); 00284 } 00285 00286 //Terminate with a line feed 00287 TRACE_DEBUG("\r\n"); 00288 } 00289
Generated on Tue Jul 12 2022 17:10:14 by
