Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
upd60611.c
Go to the documentation of this file.
00001 /** 00002 * @file upd60611.c 00003 * @brief uPD60611 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/upd60611.h" 00035 #include "debug.h" 00036 00037 00038 /** 00039 * @brief uPD60611 Ethernet PHY driver 00040 **/ 00041 00042 const PhyDriver upd60611PhyDriver = 00043 { 00044 upd60611Init, 00045 upd60611Tick, 00046 upd60611EnableIrq, 00047 upd60611DisableIrq, 00048 upd60611EventHandler, 00049 }; 00050 00051 00052 /** 00053 * @brief uPD60611 PHY transceiver initialization 00054 * @param[in] interface Underlying network interface 00055 * @return Error code 00056 **/ 00057 00058 error_t upd60611Init(NetInterface *interface) 00059 { 00060 //Debug message 00061 TRACE_INFO("Initializing uPD60611...\r\n"); 00062 00063 //Reset PHY transceiver 00064 upd60611WritePhyReg(interface, UPD60611_PHY_REG_BMCR, BMCR_RESET); 00065 //Wait for the reset to complete 00066 while(upd60611ReadPhyReg(interface, UPD60611_PHY_REG_BMCR) & BMCR_RESET); 00067 00068 //Dump PHY registers for debugging purpose 00069 upd60611DumpPhyReg(interface); 00070 00071 //Force the TCP/IP stack to poll the link state at startup 00072 interface->phyEvent = TRUE; 00073 //Notify the TCP/IP stack of the event 00074 osSetEvent(&netEvent); 00075 00076 //Successful initialization 00077 return NO_ERROR; 00078 } 00079 00080 00081 /** 00082 * @brief uPD60611 timer handler 00083 * @param[in] interface Underlying network interface 00084 **/ 00085 00086 void upd60611Tick(NetInterface *interface) 00087 { 00088 uint16_t value; 00089 bool_t linkState; 00090 00091 //Read basic status register 00092 value = upd60611ReadPhyReg(interface, UPD60611_PHY_REG_BMSR); 00093 //Retrieve current link state 00094 linkState = (value & BMSR_LINK_STATUS) ? TRUE : FALSE; 00095 00096 //Link up event? 00097 if(linkState && !interface->linkState) 00098 { 00099 //Set event flag 00100 interface->phyEvent = TRUE; 00101 //Notify the TCP/IP stack of the event 00102 osSetEvent(&netEvent); 00103 } 00104 //Link down event? 00105 else if(!linkState && interface->linkState) 00106 { 00107 //Set event flag 00108 interface->phyEvent = TRUE; 00109 //Notify the TCP/IP stack of the event 00110 osSetEvent(&netEvent); 00111 } 00112 } 00113 00114 00115 /** 00116 * @brief Enable interrupts 00117 * @param[in] interface Underlying network interface 00118 **/ 00119 00120 void upd60611EnableIrq(NetInterface *interface) 00121 { 00122 } 00123 00124 00125 /** 00126 * @brief Disable interrupts 00127 * @param[in] interface Underlying network interface 00128 **/ 00129 00130 void upd60611DisableIrq(NetInterface *interface) 00131 { 00132 } 00133 00134 00135 /** 00136 * @brief uPD60611 event handler 00137 * @param[in] interface Underlying network interface 00138 **/ 00139 00140 void upd60611EventHandler(NetInterface *interface) 00141 { 00142 uint16_t value; 00143 bool_t linkState; 00144 00145 //Any link failure condition is latched in the BMSR register... Reading 00146 //the register twice will always return the actual link status 00147 value = upd60611ReadPhyReg(interface, UPD60611_PHY_REG_BMSR); 00148 value = upd60611ReadPhyReg(interface, UPD60611_PHY_REG_BMSR); 00149 00150 //Retrieve current link state 00151 linkState = (value & BMSR_LINK_STATUS) ? TRUE : FALSE; 00152 00153 //Link is up? 00154 if(linkState && !interface->linkState) 00155 { 00156 //Read PHY special control/status register 00157 value = upd60611ReadPhyReg(interface, UPD60611_PHY_REG_PSCSR); 00158 00159 //Check current operation mode 00160 switch(value & PSCSR_HCDSPEED_MASK) 00161 { 00162 //10BASE-T 00163 case PSCSR_HCDSPEED_10BT: 00164 interface->linkSpeed = NIC_LINK_SPEED_10MBPS; 00165 interface->duplexMode = NIC_HALF_DUPLEX_MODE; 00166 break; 00167 //10BASE-T full-duplex 00168 case PSCSR_HCDSPEED_10BT_FD: 00169 interface->linkSpeed = NIC_LINK_SPEED_10MBPS; 00170 interface->duplexMode = NIC_FULL_DUPLEX_MODE; 00171 break; 00172 //100BASE-TX 00173 case PSCSR_HCDSPEED_100BTX: 00174 interface->linkSpeed = NIC_LINK_SPEED_100MBPS; 00175 interface->duplexMode = NIC_HALF_DUPLEX_MODE; 00176 break; 00177 //100BASE-TX full-duplex 00178 case PSCSR_HCDSPEED_100BTX_FD: 00179 interface->linkSpeed = NIC_LINK_SPEED_100MBPS; 00180 interface->duplexMode = NIC_FULL_DUPLEX_MODE; 00181 break; 00182 //Unknown operation mode 00183 default: 00184 //Debug message 00185 TRACE_WARNING("Invalid Duplex mode\r\n"); 00186 break; 00187 } 00188 00189 //Update link state 00190 interface->linkState = TRUE; 00191 00192 //Adjust MAC configuration parameters for proper operation 00193 interface->nicDriver->updateMacConfig(interface); 00194 00195 //Process link state change event 00196 nicNotifyLinkChange(interface); 00197 } 00198 //Link is down? 00199 else if(!linkState && interface->linkState) 00200 { 00201 //Update link state 00202 interface->linkState = FALSE; 00203 00204 //Process link state change event 00205 nicNotifyLinkChange(interface); 00206 } 00207 } 00208 00209 00210 /** 00211 * @brief Write PHY register 00212 * @param[in] interface Underlying network interface 00213 * @param[in] address PHY register address 00214 * @param[in] data Register value 00215 **/ 00216 00217 void upd60611WritePhyReg(NetInterface *interface, uint8_t address, uint16_t data) 00218 { 00219 uint8_t phyAddr; 00220 00221 //Get the address of the PHY transceiver 00222 if(interface->phyAddr < 32) 00223 phyAddr = interface->phyAddr; 00224 else 00225 phyAddr = UPD60611_PHY_ADDR; 00226 00227 //Write the specified PHY register 00228 interface->nicDriver->writePhyReg(phyAddr, address, data); 00229 } 00230 00231 00232 /** 00233 * @brief Read PHY register 00234 * @param[in] interface Underlying network interface 00235 * @param[in] address PHY register address 00236 * @return Register value 00237 **/ 00238 00239 uint16_t upd60611ReadPhyReg(NetInterface *interface, uint8_t address) 00240 { 00241 uint8_t phyAddr; 00242 00243 //Get the address of the PHY transceiver 00244 if(interface->phyAddr < 32) 00245 phyAddr = interface->phyAddr; 00246 else 00247 phyAddr = UPD60611_PHY_ADDR; 00248 00249 //Read the specified PHY register 00250 return interface->nicDriver->readPhyReg(phyAddr, address); 00251 } 00252 00253 00254 /** 00255 * @brief Dump PHY registers for debugging purpose 00256 * @param[in] interface Underlying network interface 00257 **/ 00258 00259 void upd60611DumpPhyReg(NetInterface *interface) 00260 { 00261 uint8_t i; 00262 00263 //Loop through PHY registers 00264 for(i = 0; i < 32; i++) 00265 { 00266 //Display current PHY register 00267 TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i, upd60611ReadPhyReg(interface, i)); 00268 } 00269 00270 //Terminate with a line feed 00271 TRACE_DEBUG("\r\n"); 00272 } 00273
Generated on Tue Jul 12 2022 17:10:17 by
