Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers upd60611.c Source File

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