Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers st802rt1a.c Source File

st802rt1a.c

Go to the documentation of this file.
00001 /**
00002  * @file st802rt1a.c
00003  * @brief ST802RT1A 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/st802rt1a.h"
00035 #include "debug.h"
00036 
00037 
00038 /**
00039  * @brief ST802RT1A Ethernet PHY driver
00040  **/
00041 
00042 const PhyDriver st802rt1aPhyDriver =
00043 {
00044    st802rt1aInit,
00045    st802rt1aTick,
00046    st802rt1aEnableIrq,
00047    st802rt1aDisableIrq,
00048    st802rt1aEventHandler,
00049 };
00050 
00051 
00052 /**
00053  * @brief ST802RT1A PHY transceiver initialization
00054  * @param[in] interface Underlying network interface
00055  * @return Error code
00056  **/
00057 
00058 error_t st802rt1aInit(NetInterface *interface)
00059 {
00060    //Debug message
00061    TRACE_INFO("Initializing ST802RT1A...\r\n");
00062 
00063    //Reset PHY transceiver
00064    st802rt1aWritePhyReg(interface, ST802RT1A_PHY_REG_RN00, RN00_SOFT_RESET);
00065    //Wait for the reset to complete
00066    while(st802rt1aReadPhyReg(interface, ST802RT1A_PHY_REG_RN00) & RN00_SOFT_RESET);
00067 
00068    //Dump PHY registers for debugging purpose
00069    st802rt1aDumpPhyReg(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 ST802RT1A timer handler
00083  * @param[in] interface Underlying network interface
00084  **/
00085 
00086 void st802rt1aTick(NetInterface *interface)
00087 {
00088    uint16_t value;
00089    bool_t linkState;
00090 
00091    //Read status register
00092    value = st802rt1aReadPhyReg(interface, ST802RT1A_PHY_REG_RN01);
00093    //Retrieve current link state
00094    linkState = (value & RN01_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 st802rt1aEnableIrq(NetInterface *interface)
00121 {
00122 }
00123 
00124 
00125 /**
00126  * @brief Disable interrupts
00127  * @param[in] interface Underlying network interface
00128  **/
00129 
00130 void st802rt1aDisableIrq(NetInterface *interface)
00131 {
00132 }
00133 
00134 
00135 /**
00136  * @brief ST802RT1A event handler
00137  * @param[in] interface Underlying network interface
00138  **/
00139 
00140 void st802rt1aEventHandler(NetInterface *interface)
00141 {
00142    uint16_t value;
00143    bool_t linkState;
00144 
00145    //Read status register
00146    value = st802rt1aReadPhyReg(interface, ST802RT1A_PHY_REG_RN01);
00147    //Retrieve current link state
00148    linkState = (value & RN01_LINK_STATUS) ? TRUE : FALSE;
00149 
00150    //Link is up?
00151    if(linkState && !interface->linkState)
00152    {
00153       //Read RN13 register
00154       value = st802rt1aReadPhyReg(interface, ST802RT1A_PHY_REG_RN13);
00155 
00156       //Check current operation mode
00157       switch(value & RN13_CMODE_MASK)
00158       {
00159       //10BASE-T
00160       case RN13_CMODE_10BT:
00161          interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
00162          interface->duplexMode = NIC_HALF_DUPLEX_MODE;
00163          break;
00164       //10BASE-T full-duplex
00165       case RN13_CMODE_10BT_FD:
00166          interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
00167          interface->duplexMode = NIC_FULL_DUPLEX_MODE;
00168          break;
00169       //100BASE-TX
00170       case RN13_CMODE_100BTX:
00171          interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
00172          interface->duplexMode = NIC_HALF_DUPLEX_MODE;
00173          break;
00174       //100BASE-TX full-duplex
00175       case RN13_CMODE_100BTX_FD:
00176          interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
00177          interface->duplexMode = NIC_FULL_DUPLEX_MODE;
00178          break;
00179       //Unknown operation mode
00180       default:
00181          //Debug message
00182          TRACE_WARNING("Invalid Duplex mode\r\n");
00183          break;
00184       }
00185 
00186       //Update link state
00187       interface->linkState = TRUE;
00188 
00189       //Adjust MAC configuration parameters for proper operation
00190       interface->nicDriver->updateMacConfig(interface);
00191 
00192       //Process link state change event
00193       nicNotifyLinkChange(interface);
00194    }
00195    //Link is down?
00196    else if(!linkState && interface->linkState)
00197    {
00198       //Update link state
00199       interface->linkState = FALSE;
00200 
00201       //Process link state change event
00202       nicNotifyLinkChange(interface);
00203    }
00204 }
00205 
00206 
00207 /**
00208  * @brief Write PHY register
00209  * @param[in] interface Underlying network interface
00210  * @param[in] address PHY register Register address
00211  * @param[in] data Register value
00212  **/
00213 
00214 void st802rt1aWritePhyReg(NetInterface *interface, uint8_t address, uint16_t data)
00215 {
00216    uint8_t phyAddr;
00217 
00218    //Get the address of the PHY transceiver
00219    if(interface->phyAddr < 32)
00220       phyAddr = interface->phyAddr;
00221    else
00222       phyAddr = ST802RT1A_PHY_ADDR;
00223 
00224    //Write the specified PHY register
00225    interface->nicDriver->writePhyReg(phyAddr, address, data);
00226 }
00227 
00228 
00229 /**
00230  * @brief Read PHY register
00231  * @param[in] interface Underlying network interface
00232  * @param[in] address PHY register address
00233  * @return Register value
00234  **/
00235 
00236 uint16_t st802rt1aReadPhyReg(NetInterface *interface, uint8_t address)
00237 {
00238    uint8_t phyAddr;
00239 
00240    //Get the address of the PHY transceiver
00241    if(interface->phyAddr < 32)
00242       phyAddr = interface->phyAddr;
00243    else
00244       phyAddr = ST802RT1A_PHY_ADDR;
00245 
00246    //Read the specified PHY register
00247    return interface->nicDriver->readPhyReg(phyAddr, address);
00248 }
00249 
00250 
00251 /**
00252  * @brief Dump PHY registers for debugging purpose
00253  * @param[in] interface Underlying network interface
00254  **/
00255 
00256 void st802rt1aDumpPhyReg(NetInterface *interface)
00257 {
00258    uint8_t i;
00259 
00260    //Loop through PHY registers
00261    for(i = 0; i < 32; i++)
00262    {
00263       //Display current PHY register
00264       TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i, st802rt1aReadPhyReg(interface, i));
00265    }
00266 
00267    //Terminate with a line feed
00268    TRACE_DEBUG("\r\n");
00269 }
00270