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