Adapted to Lora Semtech + Nucleo
Dependents: LoRaWAN-lmic-app LoRaWAN-lmic-app LoRaWAN-test-10secs LoRaPersonalizedDeviceForEverynet ... more
Fork of lwip_ppp_ethernet by
lpc_phy_dp83848.c
00001 /********************************************************************** 00002 * $Id$ lpc_phy_dp83848.c 2011-11-20 00003 *//** 00004 * @file lpc_phy_dp83848.c 00005 * @brief DP83848C PHY status and control. 00006 * @version 1.0 00007 * @date 20 Nov. 2011 00008 * @author NXP MCU SW Application Team 00009 * 00010 * Copyright(C) 2011, NXP Semiconductor 00011 * All rights reserved. 00012 * 00013 *********************************************************************** 00014 * Software that is described herein is for illustrative purposes only 00015 * which provides customers with programming information regarding the 00016 * products. This software is supplied "AS IS" without any warranties. 00017 * NXP Semiconductors assumes no responsibility or liability for the 00018 * use of the software, conveys no license or title under any patent, 00019 * copyright, or mask work right to the product. NXP Semiconductors 00020 * reserves the right to make changes in the software without 00021 * notification. NXP Semiconductors also make no representation or 00022 * warranty that such application will be suitable for the specified 00023 * use without further testing or modification. 00024 **********************************************************************/ 00025 00026 #include "lwip/opt.h" 00027 00028 #if NET_ETHERNET 00029 00030 #include "lwip/err.h" 00031 #include "lwip/snmp.h" 00032 #include "lpc_emac_config.h" 00033 #include "lpc_phy.h" 00034 #include "sys_arch.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_ANADV_REG 0x4 /**< Auto_Neg Advt Reg */ 00051 #define DP8_ANLPA_REG 0x5 /**< Auto_neg Link Partner Ability Reg */ 00052 #define DP8_ANEEXP_REG 0x6 /**< Auto-neg Expansion Reg */ 00053 #define DP8_PHY_STAT_REG 0x10 /**< PHY Status Register */ 00054 #define DP8_PHY_INT_CTL_REG 0x11 /**< PHY Interrupt Control Register */ 00055 #define DP8_PHY_STS_REG 0x19 /**< PHY Status Register */ 00056 00057 /** \brief DP83848 Control register definitions */ 00058 #define DP8_RESET (1 << 15) /**< 1= S/W Reset */ 00059 #define DP8_LOOPBACK (1 << 14) /**< 1=loopback Enabled */ 00060 #define DP8_SPEED_SELECT (1 << 13) /**< 1=Select 100MBps */ 00061 #define DP8_AUTONEG (1 << 12) /**< 1=Enable auto-negotiation */ 00062 #define DP8_POWER_DOWN (1 << 11) /**< 1=Power down PHY */ 00063 #define DP8_ISOLATE (1 << 10) /**< 1=Isolate PHY */ 00064 #define DP8_RESTART_AUTONEG (1 << 9) /**< 1=Restart auto-negoatiation */ 00065 #define DP8_DUPLEX_MODE (1 << 8) /**< 1=Full duplex mode */ 00066 #define DP8_COLLISION_TEST (1 << 7) /**< 1=Perform collsion test */ 00067 00068 /** \brief DP83848 Status register definitions */ 00069 #define DP8_100BASE_T4 (1 << 15) /**< T4 mode */ 00070 #define DP8_100BASE_TX_FD (1 << 14) /**< 100MBps full duplex */ 00071 #define DP8_100BASE_TX_HD (1 << 13) /**< 100MBps half duplex */ 00072 #define DP8_10BASE_T_FD (1 << 12) /**< 100Bps full duplex */ 00073 #define DP8_10BASE_T_HD (1 << 11) /**< 10MBps half duplex */ 00074 #define DP8_MF_PREAMB_SUPPR (1 << 6) /**< Preamble suppress */ 00075 #define DP8_AUTONEG_COMP (1 << 5) /**< Auto-negotation complete */ 00076 #define DP8_RMT_FAULT (1 << 4) /**< Fault */ 00077 #define DP8_AUTONEG_ABILITY (1 << 3) /**< Auto-negotation supported */ 00078 #define DP8_LINK_STATUS (1 << 2) /**< 1=Link active */ 00079 #define DP8_JABBER_DETECT (1 << 1) /**< Jabber detect */ 00080 #define DP8_EXTEND_CAPAB (1 << 0) /**< Supports extended capabilities */ 00081 00082 /** \brief DP83848 PHY status definitions */ 00083 #define DP8_REMOTEFAULT (1 << 6) /**< Remote fault */ 00084 #define DP8_FULLDUPLEX (1 << 2) /**< 1=full duplex */ 00085 #define DP8_SPEED10MBPS (1 << 1) /**< 1=10MBps speed */ 00086 #define DP8_VALID_LINK (1 << 0) /**< 1=Link active */ 00087 00088 /** \brief DP83848 PHY ID register definitions */ 00089 #define DP8_PHYID1_OUI 0x2000 /**< Expected PHY ID1 */ 00090 #define DP8_PHYID2_OUI 0x5c90 /**< Expected PHY ID2 */ 00091 00092 /** \brief PHY status structure used to indicate current status of PHY. 00093 */ 00094 typedef struct { 00095 u32_t phy_speed_100mbs:1; /**< 10/100 MBS connection speed flag. */ 00096 u32_t phy_full_duplex:1; /**< Half/full duplex connection speed flag. */ 00097 u32_t phy_link_active:1; /**< Phy link active flag. */ 00098 } PHY_STATUS_TYPE; 00099 00100 /** \brief PHY update flags */ 00101 static PHY_STATUS_TYPE physts; 00102 00103 /** \brief Last PHY update flags, used for determing if something has changed */ 00104 static PHY_STATUS_TYPE olddphysts; 00105 00106 /** \brief PHY update counter for state machine */ 00107 static s32_t phyustate; 00108 00109 /** \brief Update PHY status from passed value 00110 * 00111 * This function updates the current PHY status based on the 00112 * passed PHY status word. The PHY status indicate if the link 00113 * is active, the connection speed, and duplex. 00114 * 00115 * \param[in] netif NETIF structure 00116 * \param[in] linksts Status word from PHY 00117 * \return 1 if the status has changed, otherwise 0 00118 */ 00119 static s32_t lpc_update_phy_sts(struct netif *netif, u32_t linksts) 00120 { 00121 s32_t changed = 0; 00122 00123 /* Update link active status */ 00124 if (linksts & DP8_VALID_LINK) 00125 physts.phy_link_active = 1; 00126 else 00127 physts.phy_link_active = 0; 00128 00129 /* Full or half duplex */ 00130 if (linksts & DP8_FULLDUPLEX) 00131 physts.phy_full_duplex = 1; 00132 else 00133 physts.phy_full_duplex = 0; 00134 00135 /* Configure 100MBit/10MBit mode. */ 00136 if (linksts & DP8_SPEED10MBPS) 00137 physts.phy_speed_100mbs = 0; 00138 else 00139 physts.phy_speed_100mbs = 1; 00140 00141 if (physts.phy_speed_100mbs != olddphysts.phy_speed_100mbs) { 00142 changed = 1; 00143 if (physts.phy_speed_100mbs) { 00144 /* 100MBit mode. */ 00145 lpc_emac_set_speed(1); 00146 00147 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000); 00148 } 00149 else { 00150 /* 10MBit mode. */ 00151 lpc_emac_set_speed(0); 00152 00153 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000); 00154 } 00155 00156 olddphysts.phy_speed_100mbs = physts.phy_speed_100mbs; 00157 } 00158 00159 if (physts.phy_full_duplex != olddphysts.phy_full_duplex) { 00160 changed = 1; 00161 if (physts.phy_full_duplex) 00162 lpc_emac_set_duplex(1); 00163 else 00164 lpc_emac_set_duplex(0); 00165 00166 olddphysts.phy_full_duplex = physts.phy_full_duplex; 00167 } 00168 00169 if (physts.phy_link_active != olddphysts.phy_link_active) { 00170 changed = 1; 00171 if (physts.phy_link_active) 00172 netif_set_link_up(netif); 00173 else 00174 netif_set_link_down(netif); 00175 00176 olddphysts.phy_link_active = physts.phy_link_active; 00177 } 00178 00179 return changed; 00180 } 00181 00182 /** \brief Initialize the DP83848 PHY. 00183 * 00184 * This function initializes the DP83848 PHY. It will block until 00185 * complete. This function is called as part of the EMAC driver 00186 * initialization. Configuration of the PHY at startup is 00187 * controlled by setting up configuration defines in lpc_phy.h. 00188 * 00189 * \param[in] netif NETIF structure 00190 * \return ERR_OK if the setup was successful, otherwise ERR_TIMEOUT 00191 */ 00192 err_t lpc_phy_init(struct netif *netif) 00193 { 00194 u32_t tmp; 00195 s32_t i; 00196 00197 physts.phy_speed_100mbs = olddphysts.phy_speed_100mbs = 2; 00198 physts.phy_full_duplex = olddphysts.phy_full_duplex = 2; 00199 physts.phy_link_active = olddphysts.phy_link_active = 2; 00200 phyustate = 0; 00201 00202 /* Only first read and write are checked for failure */ 00203 /* Put the DP83848C in reset mode and wait for completion */ 00204 if (lpc_mii_write(DP8_BMCR_REG, DP8_RESET) != 0) 00205 return ERR_TIMEOUT; 00206 i = 400; 00207 while (i > 0) { 00208 osDelay(1); /* 1 ms */ 00209 if (lpc_mii_read(DP8_BMCR_REG, &tmp) != 0) 00210 return ERR_TIMEOUT; 00211 00212 if (!(tmp & (DP8_RESET | DP8_POWER_DOWN))) 00213 i = -1; 00214 else 00215 i--; 00216 } 00217 /* Timeout? */ 00218 if (i == 0) 00219 return ERR_TIMEOUT; 00220 00221 /* Setup link based on configuration options */ 00222 #if PHY_USE_AUTONEG==1 00223 tmp = DP8_AUTONEG; 00224 #else 00225 tmp = 0; 00226 #endif 00227 #if PHY_USE_100MBS==1 00228 tmp |= DP8_SPEED_SELECT; 00229 #endif 00230 #if PHY_USE_FULL_DUPLEX==1 00231 tmp |= DP8_DUPLEX_MODE; 00232 #endif 00233 lpc_mii_write(DP8_BMCR_REG, tmp); 00234 00235 /* The link is not set active at this point, but will be detected 00236 later */ 00237 00238 return ERR_OK; 00239 } 00240 00241 /* Phy status update state machine */ 00242 s32_t lpc_phy_sts_sm(struct netif *netif) 00243 { 00244 s32_t changed = 0; 00245 00246 switch (phyustate) { 00247 default: 00248 case 0: 00249 /* Read BMSR to clear faults */ 00250 lpc_mii_read_noblock(DP8_PHY_STAT_REG); 00251 phyustate = 1; 00252 break; 00253 00254 case 1: 00255 /* Wait for read status state */ 00256 if (!lpc_mii_is_busy()) { 00257 /* Update PHY status */ 00258 changed = lpc_update_phy_sts(netif, lpc_mii_read_data()); 00259 phyustate = 0; 00260 } 00261 break; 00262 } 00263 00264 return changed; 00265 } 00266 00267 #endif 00268 00269 /** 00270 * @} 00271 */ 00272 00273 /* --------------------------------- End Of File ------------------------------ */
Generated on Tue Jul 12 2022 15:12:15 by 1.7.2