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_dp83848.c
00001 #include "Target.h" 00002 00003 #ifdef TARGET_MBED 00004 /********************************************************************** 00005 * $Id$ lpc_phy_dp83848.c 2011-11-20 00006 *//** 00007 * @file lpc_phy_dp83848.c 00008 * @brief DP83848C 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 dp83848_phy PHY status and control for the DP83848. 00037 * @ingroup lwip_phy 00038 * 00039 * Various functions for controlling and monitoring the status of the 00040 * DP83848 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 DP83848 PHY register offsets */ 00048 #define DP8_BMCR_REG 0x0 /**< Basic Mode Control Register */ 00049 #define DP8_BMSR_REG 0x1 /**< Basic Mode Status Reg */ 00050 #define DP8_IDR1_REG 0x2 /**< Basic Mode Status Reg */ 00051 #define DP8_IDR2_REG 0x3 /**< Basic Mode Status Reg */ 00052 #define DP8_ANADV_REG 0x4 /**< Auto_Neg Advt Reg */ 00053 #define DP8_ANLPA_REG 0x5 /**< Auto_neg Link Partner Ability Reg */ 00054 #define DP8_ANEEXP_REG 0x6 /**< Auto-neg Expansion Reg */ 00055 #define DP8_PHY_STAT_REG 0x10 /**< PHY Status Register */ 00056 #define DP8_PHY_INT_CTL_REG 0x11 /**< PHY Interrupt Control Register */ 00057 #define DP8_PHY_RBR_REG 0x17 /**< PHY RMII and Bypass Register */ 00058 #define DP8_PHY_STS_REG 0x19 /**< PHY Status Register */ 00059 00060 #define DP8_PHY_SCSR_REG 0x1f /**< PHY Special Control/Status Register (LAN8720) */ 00061 00062 /** \brief DP83848 Control register definitions */ 00063 #define DP8_RESET (1 << 15) /**< 1= S/W Reset */ 00064 #define DP8_LOOPBACK (1 << 14) /**< 1=loopback Enabled */ 00065 #define DP8_SPEED_SELECT (1 << 13) /**< 1=Select 100MBps */ 00066 #define DP8_AUTONEG (1 << 12) /**< 1=Enable auto-negotiation */ 00067 #define DP8_POWER_DOWN (1 << 11) /**< 1=Power down PHY */ 00068 #define DP8_ISOLATE (1 << 10) /**< 1=Isolate PHY */ 00069 #define DP8_RESTART_AUTONEG (1 << 9) /**< 1=Restart auto-negoatiation */ 00070 #define DP8_DUPLEX_MODE (1 << 8) /**< 1=Full duplex mode */ 00071 #define DP8_COLLISION_TEST (1 << 7) /**< 1=Perform collsion test */ 00072 00073 /** \brief DP83848 Status register definitions */ 00074 #define DP8_100BASE_T4 (1 << 15) /**< T4 mode */ 00075 #define DP8_100BASE_TX_FD (1 << 14) /**< 100MBps full duplex */ 00076 #define DP8_100BASE_TX_HD (1 << 13) /**< 100MBps half duplex */ 00077 #define DP8_10BASE_T_FD (1 << 12) /**< 100Bps full duplex */ 00078 #define DP8_10BASE_T_HD (1 << 11) /**< 10MBps half duplex */ 00079 #define DP8_MF_PREAMB_SUPPR (1 << 6) /**< Preamble suppress */ 00080 #define DP8_AUTONEG_COMP (1 << 5) /**< Auto-negotation complete */ 00081 #define DP8_RMT_FAULT (1 << 4) /**< Fault */ 00082 #define DP8_AUTONEG_ABILITY (1 << 3) /**< Auto-negotation supported */ 00083 #define DP8_LINK_STATUS (1 << 2) /**< 1=Link active */ 00084 #define DP8_JABBER_DETECT (1 << 1) /**< Jabber detect */ 00085 #define DP8_EXTEND_CAPAB (1 << 0) /**< Supports extended capabilities */ 00086 00087 /** \brief DP83848 PHY RBR MII dode definitions */ 00088 #define DP8_RBR_RMII_MODE (1 << 5) /**< Use RMII mode */ 00089 00090 /** \brief DP83848 PHY status definitions */ 00091 #define DP8_REMOTEFAULT (1 << 6) /**< Remote fault */ 00092 #define DP8_FULLDUPLEX (1 << 2) /**< 1=full duplex */ 00093 #define DP8_SPEED10MBPS (1 << 1) /**< 1=10MBps speed */ 00094 #define DP8_VALID_LINK (1 << 0) /**< 1=Link active */ 00095 00096 /** \brief DP83848 PHY ID register definitions */ 00097 #define DP8_PHYID1_OUI 0x2000 /**< Expected PHY ID1 */ 00098 #define DP8_PHYID2_OUI 0x5c90 /**< Expected PHY ID2 */ 00099 00100 /** \brief LAN8720 PHY Special Control/Status Register */ 00101 #define PHY_SCSR_100MBIT 0x0008 /**< Speed: 1=100 MBit, 0=10Mbit */ 00102 #define PHY_SCSR_DUPLEX 0x0010 /**< PHY Duplex Mask */ 00103 00104 /** \brief Link status bits */ 00105 #define LNK_STAT_VALID 0x01 00106 #define LNK_STAT_FULLDUPLEX 0x02 00107 #define LNK_STAT_SPEED10MPS 0x04 00108 00109 /** \brief PHY ID definitions */ 00110 #define DP83848C_ID 0x20005C90 /**< PHY Identifier - DP83848C */ 00111 #define LAN8720_ID 0x0007C0F0 /**< PHY Identifier - LAN8720 */ 00112 00113 /** \brief PHY status structure used to indicate current status of PHY. 00114 */ 00115 typedef struct { 00116 u32_t phy_speed_100mbs:1; /**< 10/100 MBS connection speed flag. */ 00117 u32_t phy_full_duplex:1; /**< Half/full duplex connection speed flag. */ 00118 u32_t phy_link_active:1; /**< Phy link active flag. */ 00119 } PHY_STATUS_TYPE; 00120 00121 /** \brief PHY update flags */ 00122 static PHY_STATUS_TYPE physts; 00123 00124 /** \brief Last PHY update flags, used for determing if something has changed */ 00125 static PHY_STATUS_TYPE olddphysts; 00126 00127 /** \brief PHY update counter for state machine */ 00128 static s32_t phyustate; 00129 00130 /** \brief Holds the PHY ID */ 00131 static u32_t phy_id; 00132 00133 /** \brief Temporary holder of link status for LAN7420 */ 00134 static u32_t phy_lan7420_sts_tmp; 00135 00136 /** \brief Update PHY status from passed value 00137 * 00138 * This function updates the current PHY status based on the 00139 * passed PHY status word. The PHY status indicate if the link 00140 * is active, the connection speed, and duplex. 00141 * 00142 * \param[in] netif NETIF structure 00143 * \param[in] linksts Status word from PHY 00144 * \return 1 if the status has changed, otherwise 0 00145 */ 00146 static s32_t lpc_update_phy_sts(struct netif *netif, u32_t linksts) 00147 { 00148 s32_t changed = 0; 00149 00150 /* Update link active status */ 00151 if (linksts & LNK_STAT_VALID) 00152 physts.phy_link_active = 1; 00153 else 00154 physts.phy_link_active = 0; 00155 00156 /* Full or half duplex */ 00157 if (linksts & LNK_STAT_FULLDUPLEX) 00158 physts.phy_full_duplex = 1; 00159 else 00160 physts.phy_full_duplex = 0; 00161 00162 /* Configure 100MBit/10MBit mode. */ 00163 if (linksts & LNK_STAT_SPEED10MPS) 00164 physts.phy_speed_100mbs = 0; 00165 else 00166 physts.phy_speed_100mbs = 1; 00167 00168 if (physts.phy_speed_100mbs != olddphysts.phy_speed_100mbs) { 00169 changed = 1; 00170 if (physts.phy_speed_100mbs) { 00171 /* 100MBit mode. */ 00172 lpc_emac_set_speed(1); 00173 00174 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000); 00175 } 00176 else { 00177 /* 10MBit mode. */ 00178 lpc_emac_set_speed(0); 00179 00180 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000); 00181 } 00182 00183 olddphysts.phy_speed_100mbs = physts.phy_speed_100mbs; 00184 } 00185 00186 if (physts.phy_full_duplex != olddphysts.phy_full_duplex) { 00187 changed = 1; 00188 if (physts.phy_full_duplex) 00189 lpc_emac_set_duplex(1); 00190 else 00191 lpc_emac_set_duplex(0); 00192 00193 olddphysts.phy_full_duplex = physts.phy_full_duplex; 00194 } 00195 00196 if (physts.phy_link_active != olddphysts.phy_link_active) { 00197 changed = 1; 00198 #if NO_SYS == 1 00199 if (physts.phy_link_active) 00200 netif_set_link_up(netif); 00201 else 00202 netif_set_link_down(netif); 00203 #else 00204 if (physts.phy_link_active) 00205 tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up, 00206 (void*) netif, 1); 00207 else 00208 tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down, 00209 (void*) netif, 1); 00210 #endif 00211 00212 olddphysts.phy_link_active = physts.phy_link_active; 00213 } 00214 00215 return changed; 00216 } 00217 00218 /** \brief Initialize the DP83848 PHY. 00219 * 00220 * This function initializes the DP83848 PHY. It will block until 00221 * complete. This function is called as part of the EMAC driver 00222 * initialization. Configuration of the PHY at startup is 00223 * controlled by setting up configuration defines in lpc_phy.h. 00224 * 00225 * \param[in] netif NETIF structure 00226 * \param[in] rmii If set, configures the PHY for RMII mode 00227 * \return ERR_OK if the setup was successful, otherwise ERR_TIMEOUT 00228 */ 00229 err_t lpc_phy_init(struct netif *netif, int rmii) 00230 { 00231 u32_t tmp; 00232 s32_t i; 00233 00234 physts.phy_speed_100mbs = olddphysts.phy_speed_100mbs = 2; 00235 physts.phy_full_duplex = olddphysts.phy_full_duplex = 2; 00236 physts.phy_link_active = olddphysts.phy_link_active = 2; 00237 phyustate = 0; 00238 00239 /* Only first read and write are checked for failure */ 00240 /* Put the DP83848C in reset mode and wait for completion */ 00241 if (lpc_mii_write(DP8_BMCR_REG, DP8_RESET) != 0) 00242 return ERR_TIMEOUT; 00243 i = 400; 00244 while (i > 0) { 00245 osDelay(1); /* 1 ms */ 00246 if (lpc_mii_read(DP8_BMCR_REG, &tmp) != 0) 00247 return ERR_TIMEOUT; 00248 00249 if (!(tmp & (DP8_RESET | DP8_POWER_DOWN))) 00250 i = -1; 00251 else 00252 i--; 00253 } 00254 /* Timeout? */ 00255 if (i == 0) 00256 return ERR_TIMEOUT; 00257 00258 // read PHY ID 00259 lpc_mii_read(DP8_IDR1_REG, &tmp); 00260 phy_id = (tmp << 16); 00261 lpc_mii_read(DP8_IDR2_REG, &tmp); 00262 phy_id |= (tmp & 0XFFF0); 00263 00264 /* Setup link based on configuration options */ 00265 #if PHY_USE_AUTONEG==1 00266 tmp = DP8_AUTONEG; 00267 #else 00268 tmp = 0; 00269 #endif 00270 #if PHY_USE_100MBS==1 00271 tmp |= DP8_SPEED_SELECT; 00272 #endif 00273 #if PHY_USE_FULL_DUPLEX==1 00274 tmp |= DP8_DUPLEX_MODE; 00275 #endif 00276 lpc_mii_write(DP8_BMCR_REG, tmp); 00277 00278 /* Enable RMII mode for PHY */ 00279 if (rmii) 00280 lpc_mii_write(DP8_PHY_RBR_REG, DP8_RBR_RMII_MODE); 00281 00282 /* The link is not set active at this point, but will be detected 00283 later */ 00284 00285 return ERR_OK; 00286 } 00287 00288 /* Phy status update state machine */ 00289 s32_t lpc_phy_sts_sm(struct netif *netif) 00290 { 00291 s32_t changed = 0; 00292 u32_t data = 0; 00293 u32_t tmp; 00294 00295 switch (phyustate) { 00296 default: 00297 case 0: 00298 if (phy_id == DP83848C_ID) { 00299 lpc_mii_read_noblock(DP8_PHY_STAT_REG); 00300 phyustate = 2; 00301 } 00302 else if (phy_id == LAN8720_ID) { 00303 lpc_mii_read_noblock(DP8_PHY_SCSR_REG); 00304 phyustate = 1; 00305 } 00306 break; 00307 00308 case 1: 00309 if (phy_id == LAN8720_ID) { 00310 tmp = lpc_mii_read_data(); 00311 // we get speed and duplex here. 00312 phy_lan7420_sts_tmp = (tmp & PHY_SCSR_DUPLEX) ? LNK_STAT_FULLDUPLEX : 0; 00313 phy_lan7420_sts_tmp |= (tmp & PHY_SCSR_100MBIT) ? 0 : LNK_STAT_SPEED10MPS; 00314 00315 //read the status register to get link status 00316 lpc_mii_read_noblock(DP8_BMSR_REG); 00317 phyustate = 2; 00318 } 00319 break; 00320 00321 case 2: 00322 /* Wait for read status state */ 00323 if (!lpc_mii_is_busy()) { 00324 /* Update PHY status */ 00325 tmp = lpc_mii_read_data(); 00326 00327 if (phy_id == DP83848C_ID) { 00328 // STS register contains all needed status bits 00329 data = (tmp & DP8_VALID_LINK) ? LNK_STAT_VALID : 0; 00330 data |= (tmp & DP8_FULLDUPLEX) ? LNK_STAT_FULLDUPLEX : 0; 00331 data |= (tmp & DP8_SPEED10MBPS) ? LNK_STAT_SPEED10MPS : 0; 00332 } 00333 else if (phy_id == LAN8720_ID) { 00334 // we only get the link status here. 00335 phy_lan7420_sts_tmp |= (tmp & DP8_LINK_STATUS) ? LNK_STAT_VALID : 0; 00336 data = phy_lan7420_sts_tmp; 00337 } 00338 00339 changed = lpc_update_phy_sts(netif, data); 00340 phyustate = 0; 00341 } 00342 break; 00343 } 00344 00345 return changed; 00346 } 00347 00348 /** 00349 * @} 00350 */ 00351 00352 /* --------------------------------- End Of File ------------------------------ */ 00353 #endif
Generated on Tue Jul 12 2022 17:52:03 by 1.7.2