A web server for monitoring and controlling a MakerBot Replicator over the USB host and ethernet.
Dependencies: IAP NTPClient RTC mbed-rtos mbed Socket lwip-sys lwip BurstSPI
Fork of LPC1768_Mini-DK by
lpc_phy_lan8720.c
00001 #include "Target.h" 00002 #ifdef TARGET_MINIDK 00003 00004 /********************************************************************** 00005 * $Id$ lpc_phy_lan8720.c 2011-11-20 00006 *//** 00007 * @file lpc_phy_lan8720.c 00008 * @brief LAN8720 PHY status and control. 00009 * @version 1.0 00010 * @date 20 Nov. 2011 00011 * @author NXP MCU SW Application Team 00012 * 00013 * Copyright(C) 2011, NXP Semiconductor 00014 * All rights reserved. 00015 * 00016 *********************************************************************** 00017 * Software that is described herein is for illustrative purposes only 00018 * which provides customers with programming information regarding the 00019 * products. This software is supplied "AS IS" without any warranties. 00020 * NXP Semiconductors assumes no responsibility or liability for the 00021 * use of the software, conveys no license or title under any patent, 00022 * copyright, or mask work right to the product. NXP Semiconductors 00023 * reserves the right to make changes in the software without 00024 * notification. NXP Semiconductors also make no representation or 00025 * warranty that such application will be suitable for the specified 00026 * use without further testing or modification. 00027 **********************************************************************/ 00028 00029 #include "lwip/opt.h" 00030 #include "lwip/err.h" 00031 #include "lwip/tcpip.h" 00032 #include "lwip/snmp.h" 00033 #include "lpc_emac_config.h" 00034 #include "lpc_phy.h" 00035 00036 /** @defgroup lan8720_phy PHY status and control for the LAN8720. 00037 * @ingroup lwip_phy 00038 * 00039 * Various functions for controlling and monitoring the status of the 00040 * LAN8720 PHY. In polled (standalone) systems, the PHY state must be 00041 * monitored as part of the application. In a threaded (RTOS) system, 00042 * the PHY state is monitored by the PHY handler thread. The MAC 00043 * driver will not transmit unless the PHY link is active. 00044 * @{ 00045 */ 00046 00047 /** \brief LAN8720 PHY register offsets */ 00048 #define LAN8_BCR_REG 0x0 /**< Basic Control Register */ 00049 #define LAN8_BSR_REG 0x1 /**< Basic Status Reg */ 00050 #define LAN8_PHYID1_REG 0x2 /**< PHY ID 1 Reg */ 00051 #define LAN8_PHYID2_REG 0x3 /**< PHY ID 2 Reg */ 00052 #define LAN8_PHYSPLCTL_REG 0x1F /**< PHY special control/status Reg */ 00053 00054 /* LAN8720 BCR register definitions */ 00055 #define LAN8_RESET (1 << 15) /**< 1= S/W Reset */ 00056 #define LAN8_LOOPBACK (1 << 14) /**< 1=loopback Enabled */ 00057 #define LAN8_SPEED_SELECT (1 << 13) /**< 1=Select 100MBps */ 00058 #define LAN8_AUTONEG (1 << 12) /**< 1=Enable auto-negotiation */ 00059 #define LAN8_POWER_DOWN (1 << 11) /**< 1=Power down PHY */ 00060 #define LAN8_ISOLATE (1 << 10) /**< 1=Isolate PHY */ 00061 #define LAN8_RESTART_AUTONEG (1 << 9) /**< 1=Restart auto-negoatiation */ 00062 #define LAN8_DUPLEX_MODE (1 << 8) /**< 1=Full duplex mode */ 00063 00064 /* LAN8720 BSR register definitions */ 00065 #define LAN8_100BASE_T4 (1 << 15) /**< T4 mode */ 00066 #define LAN8_100BASE_TX_FD (1 << 14) /**< 100MBps full duplex */ 00067 #define LAN8_100BASE_TX_HD (1 << 13) /**< 100MBps half duplex */ 00068 #define LAN8_10BASE_T_FD (1 << 12) /**< 100Bps full duplex */ 00069 #define LAN8_10BASE_T_HD (1 << 11) /**< 10MBps half duplex */ 00070 #define LAN8_AUTONEG_COMP (1 << 5) /**< Auto-negotation complete */ 00071 #define LAN8_RMT_FAULT (1 << 4) /**< Fault */ 00072 #define LAN8_AUTONEG_ABILITY (1 << 3) /**< Auto-negotation supported */ 00073 #define LAN8_LINK_STATUS (1 << 2) /**< 1=Link active */ 00074 #define LAN8_JABBER_DETECT (1 << 1) /**< Jabber detect */ 00075 #define LAN8_EXTEND_CAPAB (1 << 0) /**< Supports extended capabilities */ 00076 00077 /* LAN8720 PHYSPLCTL status definitions */ 00078 #define LAN8_SPEEDMASK (7 << 2) /**< Speed and duplex mask */ 00079 #define LAN8_SPEED100F (6 << 2) /**< 100BT full duplex */ 00080 #define LAN8_SPEED10F (5 << 2) /**< 10BT full duplex */ 00081 #define LAN8_SPEED100H (2 << 2) /**< 100BT half duplex */ 00082 #define LAN8_SPEED10H (1 << 2) /**< 10BT half duplex */ 00083 00084 /* LAN8720 PHY ID 1/2 register definitions */ 00085 #define LAN8_PHYID1_OUI 0x0007 /**< Expected PHY ID1 */ 00086 #define LAN8_PHYID2_OUI 0xC0F0 /**< Expected PHY ID2, except last 4 bits */ 00087 00088 /** 00089 * @brief PHY status structure used to indicate current status of PHY. 00090 */ 00091 typedef struct { 00092 u32_t phy_speed_100mbs:2; /**< 10/100 MBS connection speed flag. */ 00093 u32_t phy_full_duplex:2; /**< Half/full duplex connection speed flag. */ 00094 u32_t phy_link_active:2; /**< Phy link active flag. */ 00095 } PHY_STATUS_TYPE; 00096 00097 /** \brief PHY update flags */ 00098 static PHY_STATUS_TYPE physts; 00099 00100 /** \brief Last PHY update flags, used for determing if something has changed */ 00101 static PHY_STATUS_TYPE olddphysts; 00102 00103 /** \brief PHY update counter for state machine */ 00104 static s32_t phyustate; 00105 00106 /** \brief Update PHY status from passed value 00107 * 00108 * This function updates the current PHY status based on the 00109 * passed PHY status word. The PHY status indicate if the link 00110 * is active, the connection speed, and duplex. 00111 * 00112 * \param[in] netif NETIF structure 00113 * \param[in] linksts Status word with link state 00114 * \param[in] sdsts Status word with speed and duplex states 00115 * \return 1 if the status has changed, otherwise 0 00116 */ 00117 static s32_t lpc_update_phy_sts(struct netif *netif, u32_t linksts, u32_t sdsts) 00118 { 00119 s32_t changed = 0; 00120 00121 /* Update link active status */ 00122 if (linksts & LAN8_LINK_STATUS) 00123 physts.phy_link_active = 1; 00124 else 00125 physts.phy_link_active = 0; 00126 00127 switch (sdsts & LAN8_SPEEDMASK) { 00128 case LAN8_SPEED100F: 00129 default: 00130 physts.phy_speed_100mbs = 1; 00131 physts.phy_full_duplex = 1; 00132 break; 00133 00134 case LAN8_SPEED10F: 00135 physts.phy_speed_100mbs = 0; 00136 physts.phy_full_duplex = 1; 00137 break; 00138 00139 case LAN8_SPEED100H: 00140 physts.phy_speed_100mbs = 1; 00141 physts.phy_full_duplex = 0; 00142 break; 00143 00144 case LAN8_SPEED10H: 00145 physts.phy_speed_100mbs = 0; 00146 physts.phy_full_duplex = 0; 00147 break; 00148 } 00149 00150 if (physts.phy_speed_100mbs != olddphysts.phy_speed_100mbs) { 00151 changed = 1; 00152 if (physts.phy_speed_100mbs) { 00153 /* 100MBit mode. */ 00154 lpc_emac_set_speed(1); 00155 00156 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000); 00157 } 00158 else { 00159 /* 10MBit mode. */ 00160 lpc_emac_set_speed(0); 00161 00162 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000); 00163 } 00164 00165 olddphysts.phy_speed_100mbs = physts.phy_speed_100mbs; 00166 } 00167 00168 if (physts.phy_full_duplex != olddphysts.phy_full_duplex) { 00169 changed = 1; 00170 if (physts.phy_full_duplex) 00171 lpc_emac_set_duplex(1); 00172 else 00173 lpc_emac_set_duplex(0); 00174 00175 olddphysts.phy_full_duplex = physts.phy_full_duplex; 00176 } 00177 00178 if (physts.phy_link_active != olddphysts.phy_link_active) { 00179 changed = 1; 00180 #if NO_SYS == 1 00181 if (physts.phy_link_active) 00182 netif_set_link_up(netif); 00183 else 00184 netif_set_link_down(netif); 00185 #else 00186 if (physts.phy_link_active) 00187 tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up, 00188 (void*) netif, 1); 00189 else 00190 tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down, 00191 (void*) netif, 1); 00192 #endif 00193 00194 olddphysts.phy_link_active = physts.phy_link_active; 00195 } 00196 00197 return changed; 00198 } 00199 00200 /** \brief Initialize the LAN8720 PHY. 00201 * 00202 * This function initializes the LAN8720 PHY. It will block until 00203 * complete. This function is called as part of the EMAC driver 00204 * initialization. Configuration of the PHY at startup is 00205 * controlled by setting up configuration defines in 00206 * lpc_emac_config.h. 00207 * 00208 * \param[in] netif NETIF structure 00209 * \param[in] rmii If set, configures the PHY for RMII mode 00210 * \return ERR_OK if the setup was successful, otherwise ERR_TIMEOUT 00211 */ 00212 err_t lpc_phy_init(struct netif *netif, int rmii) 00213 { 00214 u32_t tmp;//, tmp1; 00215 s32_t i; 00216 00217 physts.phy_speed_100mbs = olddphysts.phy_speed_100mbs = 2; 00218 physts.phy_full_duplex = olddphysts.phy_full_duplex = 2; 00219 physts.phy_link_active = olddphysts.phy_link_active = 2; 00220 phyustate = 0; 00221 00222 /* Only first read and write are checked for failure */ 00223 /* Put the LAN8720 in reset mode and wait for completion */ 00224 if (lpc_mii_write(LAN8_BCR_REG, LAN8_RESET) != 0) 00225 return ERR_TIMEOUT; 00226 i = 400; 00227 while (i > 0) { 00228 osDelay(1); /* 1 ms */ 00229 if (lpc_mii_read(LAN8_BCR_REG, &tmp) != 0) 00230 return ERR_TIMEOUT; 00231 00232 if (!(tmp & (LAN8_RESET | LAN8_POWER_DOWN))) 00233 i = -1; 00234 else 00235 i--; 00236 } 00237 /* Timeout? */ 00238 if (i == 0) 00239 return ERR_TIMEOUT; 00240 00241 /* Setup link based on configuration options */ 00242 #if PHY_USE_AUTONEG==1 00243 tmp = LAN8_AUTONEG; 00244 #else 00245 tmp = 0; 00246 #endif 00247 #if PHY_USE_100MBS==1 00248 tmp |= LAN8_SPEED_SELECT; 00249 #endif 00250 #if PHY_USE_FULL_DUPLEX==1 00251 tmp |= LAN8_DUPLEX_MODE; 00252 #endif 00253 lpc_mii_write(LAN8_BCR_REG, tmp); 00254 00255 /* The link is not set active at this point, but will be detected 00256 later */ 00257 00258 return ERR_OK; 00259 } 00260 00261 /* Phy status update state machine */ 00262 s32_t lpc_phy_sts_sm(struct netif *netif) 00263 { 00264 static u32_t sts; 00265 s32_t changed = 0; 00266 00267 switch (phyustate) { 00268 default: 00269 case 0: 00270 /* Read BMSR to clear faults */ 00271 lpc_mii_read_noblock(LAN8_BSR_REG); 00272 phyustate = 1; 00273 break; 00274 00275 case 1: 00276 /* Wait for read status state */ 00277 if (!lpc_mii_is_busy()) { 00278 /* Get PHY status with link state */ 00279 sts = lpc_mii_read_data(); 00280 lpc_mii_read_noblock(LAN8_PHYSPLCTL_REG); 00281 phyustate = 2; 00282 } 00283 break; 00284 00285 case 2: 00286 /* Wait for read status state */ 00287 if (!lpc_mii_is_busy()) { 00288 /* Update PHY status */ 00289 changed = lpc_update_phy_sts(netif, sts, lpc_mii_read_data()); 00290 phyustate = 0; 00291 } 00292 break; 00293 } 00294 00295 return changed; 00296 } 00297 00298 /** 00299 * @} 00300 */ 00301 00302 /* --------------------------------- End Of File ------------------------------ */ 00303 #endif
Generated on Tue Jul 12 2022 17:52:03 by 1.7.2