Donatien Garnier / LwIPNetworking

Dependencies:   DebugLib Socket lwip lwip-sys

Dependents:   EthernetInterface

Fork of NetworkingCoreLib by Donatien Garnier

Committer:
donatien
Date:
Thu May 24 14:49:40 2012 +0000
Revision:
0:013f5d54248c
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:013f5d54248c 1 /**********************************************************************
donatien 0:013f5d54248c 2 * $Id$ lpc_phy_dp83848.c 2011-11-20
donatien 0:013f5d54248c 3 *//**
donatien 0:013f5d54248c 4 * @file lpc_phy_dp83848.c
donatien 0:013f5d54248c 5 * @brief DP83848C PHY status and control.
donatien 0:013f5d54248c 6 * @version 1.0
donatien 0:013f5d54248c 7 * @date 20 Nov. 2011
donatien 0:013f5d54248c 8 * @author NXP MCU SW Application Team
donatien 0:013f5d54248c 9 *
donatien 0:013f5d54248c 10 * Copyright(C) 2011, NXP Semiconductor
donatien 0:013f5d54248c 11 * All rights reserved.
donatien 0:013f5d54248c 12 *
donatien 0:013f5d54248c 13 ***********************************************************************
donatien 0:013f5d54248c 14 * Software that is described herein is for illustrative purposes only
donatien 0:013f5d54248c 15 * which provides customers with programming information regarding the
donatien 0:013f5d54248c 16 * products. This software is supplied "AS IS" without any warranties.
donatien 0:013f5d54248c 17 * NXP Semiconductors assumes no responsibility or liability for the
donatien 0:013f5d54248c 18 * use of the software, conveys no license or title under any patent,
donatien 0:013f5d54248c 19 * copyright, or mask work right to the product. NXP Semiconductors
donatien 0:013f5d54248c 20 * reserves the right to make changes in the software without
donatien 0:013f5d54248c 21 * notification. NXP Semiconductors also make no representation or
donatien 0:013f5d54248c 22 * warranty that such application will be suitable for the specified
donatien 0:013f5d54248c 23 * use without further testing or modification.
donatien 0:013f5d54248c 24 **********************************************************************/
donatien 0:013f5d54248c 25
donatien 0:013f5d54248c 26 #include "lwip/opt.h"
donatien 0:013f5d54248c 27 #include "lwip/err.h"
donatien 0:013f5d54248c 28 #include "lwip/snmp.h"
donatien 0:013f5d54248c 29 #include "lpc_emac_config.h"
donatien 0:013f5d54248c 30 #include "lpc_phy.h"
donatien 0:013f5d54248c 31 #include "sys_arch.h"
donatien 0:013f5d54248c 32
donatien 0:013f5d54248c 33 /** @defgroup dp83848_phy PHY status and control for the DP83848.
donatien 0:013f5d54248c 34 * @ingroup lwip_phy
donatien 0:013f5d54248c 35 *
donatien 0:013f5d54248c 36 * Various functions for controlling and monitoring the status of the
donatien 0:013f5d54248c 37 * DP83848 PHY. In polled (standalone) systems, the PHY state must be
donatien 0:013f5d54248c 38 * monitored as part of the application. In a threaded (RTOS) system,
donatien 0:013f5d54248c 39 * the PHY state is monitored by the PHY handler thread. The MAC
donatien 0:013f5d54248c 40 * driver will not transmit unless the PHY link is active.
donatien 0:013f5d54248c 41 * @{
donatien 0:013f5d54248c 42 */
donatien 0:013f5d54248c 43
donatien 0:013f5d54248c 44 /** \brief DP83848 PHY register offsets */
donatien 0:013f5d54248c 45 #define DP8_BMCR_REG 0x0 /**< Basic Mode Control Register */
donatien 0:013f5d54248c 46 #define DP8_BMSR_REG 0x1 /**< Basic Mode Status Reg */
donatien 0:013f5d54248c 47 #define DP8_ANADV_REG 0x4 /**< Auto_Neg Advt Reg */
donatien 0:013f5d54248c 48 #define DP8_ANLPA_REG 0x5 /**< Auto_neg Link Partner Ability Reg */
donatien 0:013f5d54248c 49 #define DP8_ANEEXP_REG 0x6 /**< Auto-neg Expansion Reg */
donatien 0:013f5d54248c 50 #define DP8_PHY_STAT_REG 0x10 /**< PHY Status Register */
donatien 0:013f5d54248c 51 #define DP8_PHY_INT_CTL_REG 0x11 /**< PHY Interrupt Control Register */
donatien 0:013f5d54248c 52 #define DP8_PHY_STS_REG 0x19 /**< PHY Status Register */
donatien 0:013f5d54248c 53
donatien 0:013f5d54248c 54 /** \brief DP83848 Control register definitions */
donatien 0:013f5d54248c 55 #define DP8_RESET (1 << 15) /**< 1= S/W Reset */
donatien 0:013f5d54248c 56 #define DP8_LOOPBACK (1 << 14) /**< 1=loopback Enabled */
donatien 0:013f5d54248c 57 #define DP8_SPEED_SELECT (1 << 13) /**< 1=Select 100MBps */
donatien 0:013f5d54248c 58 #define DP8_AUTONEG (1 << 12) /**< 1=Enable auto-negotiation */
donatien 0:013f5d54248c 59 #define DP8_POWER_DOWN (1 << 11) /**< 1=Power down PHY */
donatien 0:013f5d54248c 60 #define DP8_ISOLATE (1 << 10) /**< 1=Isolate PHY */
donatien 0:013f5d54248c 61 #define DP8_RESTART_AUTONEG (1 << 9) /**< 1=Restart auto-negoatiation */
donatien 0:013f5d54248c 62 #define DP8_DUPLEX_MODE (1 << 8) /**< 1=Full duplex mode */
donatien 0:013f5d54248c 63 #define DP8_COLLISION_TEST (1 << 7) /**< 1=Perform collsion test */
donatien 0:013f5d54248c 64
donatien 0:013f5d54248c 65 /** \brief DP83848 Status register definitions */
donatien 0:013f5d54248c 66 #define DP8_100BASE_T4 (1 << 15) /**< T4 mode */
donatien 0:013f5d54248c 67 #define DP8_100BASE_TX_FD (1 << 14) /**< 100MBps full duplex */
donatien 0:013f5d54248c 68 #define DP8_100BASE_TX_HD (1 << 13) /**< 100MBps half duplex */
donatien 0:013f5d54248c 69 #define DP8_10BASE_T_FD (1 << 12) /**< 100Bps full duplex */
donatien 0:013f5d54248c 70 #define DP8_10BASE_T_HD (1 << 11) /**< 10MBps half duplex */
donatien 0:013f5d54248c 71 #define DP8_MF_PREAMB_SUPPR (1 << 6) /**< Preamble suppress */
donatien 0:013f5d54248c 72 #define DP8_AUTONEG_COMP (1 << 5) /**< Auto-negotation complete */
donatien 0:013f5d54248c 73 #define DP8_RMT_FAULT (1 << 4) /**< Fault */
donatien 0:013f5d54248c 74 #define DP8_AUTONEG_ABILITY (1 << 3) /**< Auto-negotation supported */
donatien 0:013f5d54248c 75 #define DP8_LINK_STATUS (1 << 2) /**< 1=Link active */
donatien 0:013f5d54248c 76 #define DP8_JABBER_DETECT (1 << 1) /**< Jabber detect */
donatien 0:013f5d54248c 77 #define DP8_EXTEND_CAPAB (1 << 0) /**< Supports extended capabilities */
donatien 0:013f5d54248c 78
donatien 0:013f5d54248c 79 /** \brief DP83848 PHY status definitions */
donatien 0:013f5d54248c 80 #define DP8_REMOTEFAULT (1 << 6) /**< Remote fault */
donatien 0:013f5d54248c 81 #define DP8_FULLDUPLEX (1 << 2) /**< 1=full duplex */
donatien 0:013f5d54248c 82 #define DP8_SPEED10MBPS (1 << 1) /**< 1=10MBps speed */
donatien 0:013f5d54248c 83 #define DP8_VALID_LINK (1 << 0) /**< 1=Link active */
donatien 0:013f5d54248c 84
donatien 0:013f5d54248c 85 /** \brief DP83848 PHY ID register definitions */
donatien 0:013f5d54248c 86 #define DP8_PHYID1_OUI 0x2000 /**< Expected PHY ID1 */
donatien 0:013f5d54248c 87 #define DP8_PHYID2_OUI 0x5c90 /**< Expected PHY ID2 */
donatien 0:013f5d54248c 88
donatien 0:013f5d54248c 89 /** \brief PHY status structure used to indicate current status of PHY.
donatien 0:013f5d54248c 90 */
donatien 0:013f5d54248c 91 typedef struct {
donatien 0:013f5d54248c 92 u32_t phy_speed_100mbs:1; /**< 10/100 MBS connection speed flag. */
donatien 0:013f5d54248c 93 u32_t phy_full_duplex:1; /**< Half/full duplex connection speed flag. */
donatien 0:013f5d54248c 94 u32_t phy_link_active:1; /**< Phy link active flag. */
donatien 0:013f5d54248c 95 } PHY_STATUS_TYPE;
donatien 0:013f5d54248c 96
donatien 0:013f5d54248c 97 /** \brief PHY update flags */
donatien 0:013f5d54248c 98 static PHY_STATUS_TYPE physts;
donatien 0:013f5d54248c 99
donatien 0:013f5d54248c 100 /** \brief Last PHY update flags, used for determing if something has changed */
donatien 0:013f5d54248c 101 static PHY_STATUS_TYPE olddphysts;
donatien 0:013f5d54248c 102
donatien 0:013f5d54248c 103 /** \brief PHY update counter for state machine */
donatien 0:013f5d54248c 104 static s32_t phyustate;
donatien 0:013f5d54248c 105
donatien 0:013f5d54248c 106 /** \brief Update PHY status from passed value
donatien 0:013f5d54248c 107 *
donatien 0:013f5d54248c 108 * This function updates the current PHY status based on the
donatien 0:013f5d54248c 109 * passed PHY status word. The PHY status indicate if the link
donatien 0:013f5d54248c 110 * is active, the connection speed, and duplex.
donatien 0:013f5d54248c 111 *
donatien 0:013f5d54248c 112 * \param[in] netif NETIF structure
donatien 0:013f5d54248c 113 * \param[in] linksts Status word from PHY
donatien 0:013f5d54248c 114 * \return 1 if the status has changed, otherwise 0
donatien 0:013f5d54248c 115 */
donatien 0:013f5d54248c 116 static s32_t lpc_update_phy_sts(struct netif *netif, u32_t linksts)
donatien 0:013f5d54248c 117 {
donatien 0:013f5d54248c 118 s32_t changed = 0;
donatien 0:013f5d54248c 119
donatien 0:013f5d54248c 120 /* Update link active status */
donatien 0:013f5d54248c 121 if (linksts & DP8_VALID_LINK)
donatien 0:013f5d54248c 122 physts.phy_link_active = 1;
donatien 0:013f5d54248c 123 else
donatien 0:013f5d54248c 124 physts.phy_link_active = 0;
donatien 0:013f5d54248c 125
donatien 0:013f5d54248c 126 /* Full or half duplex */
donatien 0:013f5d54248c 127 if (linksts & DP8_FULLDUPLEX)
donatien 0:013f5d54248c 128 physts.phy_full_duplex = 1;
donatien 0:013f5d54248c 129 else
donatien 0:013f5d54248c 130 physts.phy_full_duplex = 0;
donatien 0:013f5d54248c 131
donatien 0:013f5d54248c 132 /* Configure 100MBit/10MBit mode. */
donatien 0:013f5d54248c 133 if (linksts & DP8_SPEED10MBPS)
donatien 0:013f5d54248c 134 physts.phy_speed_100mbs = 0;
donatien 0:013f5d54248c 135 else
donatien 0:013f5d54248c 136 physts.phy_speed_100mbs = 1;
donatien 0:013f5d54248c 137
donatien 0:013f5d54248c 138 if (physts.phy_speed_100mbs != olddphysts.phy_speed_100mbs) {
donatien 0:013f5d54248c 139 changed = 1;
donatien 0:013f5d54248c 140 if (physts.phy_speed_100mbs) {
donatien 0:013f5d54248c 141 /* 100MBit mode. */
donatien 0:013f5d54248c 142 lpc_emac_set_speed(1);
donatien 0:013f5d54248c 143
donatien 0:013f5d54248c 144 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
donatien 0:013f5d54248c 145 }
donatien 0:013f5d54248c 146 else {
donatien 0:013f5d54248c 147 /* 10MBit mode. */
donatien 0:013f5d54248c 148 lpc_emac_set_speed(0);
donatien 0:013f5d54248c 149
donatien 0:013f5d54248c 150 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
donatien 0:013f5d54248c 151 }
donatien 0:013f5d54248c 152
donatien 0:013f5d54248c 153 olddphysts.phy_speed_100mbs = physts.phy_speed_100mbs;
donatien 0:013f5d54248c 154 }
donatien 0:013f5d54248c 155
donatien 0:013f5d54248c 156 if (physts.phy_full_duplex != olddphysts.phy_full_duplex) {
donatien 0:013f5d54248c 157 changed = 1;
donatien 0:013f5d54248c 158 if (physts.phy_full_duplex)
donatien 0:013f5d54248c 159 lpc_emac_set_duplex(1);
donatien 0:013f5d54248c 160 else
donatien 0:013f5d54248c 161 lpc_emac_set_duplex(0);
donatien 0:013f5d54248c 162
donatien 0:013f5d54248c 163 olddphysts.phy_full_duplex = physts.phy_full_duplex;
donatien 0:013f5d54248c 164 }
donatien 0:013f5d54248c 165
donatien 0:013f5d54248c 166 if (physts.phy_link_active != olddphysts.phy_link_active) {
donatien 0:013f5d54248c 167 changed = 1;
donatien 0:013f5d54248c 168 if (physts.phy_link_active)
donatien 0:013f5d54248c 169 netif_set_link_up(netif);
donatien 0:013f5d54248c 170 else
donatien 0:013f5d54248c 171 netif_set_link_down(netif);
donatien 0:013f5d54248c 172
donatien 0:013f5d54248c 173 olddphysts.phy_link_active = physts.phy_link_active;
donatien 0:013f5d54248c 174 }
donatien 0:013f5d54248c 175
donatien 0:013f5d54248c 176 return changed;
donatien 0:013f5d54248c 177 }
donatien 0:013f5d54248c 178
donatien 0:013f5d54248c 179 /** \brief Initialize the DP83848 PHY.
donatien 0:013f5d54248c 180 *
donatien 0:013f5d54248c 181 * This function initializes the DP83848 PHY. It will block until
donatien 0:013f5d54248c 182 * complete. This function is called as part of the EMAC driver
donatien 0:013f5d54248c 183 * initialization. Configuration of the PHY at startup is
donatien 0:013f5d54248c 184 * controlled by setting up configuration defines in lpc_phy.h.
donatien 0:013f5d54248c 185 *
donatien 0:013f5d54248c 186 * \param[in] netif NETIF structure
donatien 0:013f5d54248c 187 * \return ERR_OK if the setup was successful, otherwise ERR_TIMEOUT
donatien 0:013f5d54248c 188 */
donatien 0:013f5d54248c 189 err_t lpc_phy_init(struct netif *netif)
donatien 0:013f5d54248c 190 {
donatien 0:013f5d54248c 191 u32_t tmp;
donatien 0:013f5d54248c 192 s32_t i;
donatien 0:013f5d54248c 193
donatien 0:013f5d54248c 194 physts.phy_speed_100mbs = olddphysts.phy_speed_100mbs = 2;
donatien 0:013f5d54248c 195 physts.phy_full_duplex = olddphysts.phy_full_duplex = 2;
donatien 0:013f5d54248c 196 physts.phy_link_active = olddphysts.phy_link_active = 2;
donatien 0:013f5d54248c 197 phyustate = 0;
donatien 0:013f5d54248c 198
donatien 0:013f5d54248c 199 /* Only first read and write are checked for failure */
donatien 0:013f5d54248c 200 /* Put the DP83848C in reset mode and wait for completion */
donatien 0:013f5d54248c 201 if (lpc_mii_write(DP8_BMCR_REG, DP8_RESET) != 0)
donatien 0:013f5d54248c 202 return ERR_TIMEOUT;
donatien 0:013f5d54248c 203 i = 400;
donatien 0:013f5d54248c 204 while (i > 0) {
donatien 0:013f5d54248c 205 osDelay(1); /* 1 ms */
donatien 0:013f5d54248c 206 if (lpc_mii_read(DP8_BMCR_REG, &tmp) != 0)
donatien 0:013f5d54248c 207 return ERR_TIMEOUT;
donatien 0:013f5d54248c 208
donatien 0:013f5d54248c 209 if (!(tmp & (DP8_RESET | DP8_POWER_DOWN)))
donatien 0:013f5d54248c 210 i = -1;
donatien 0:013f5d54248c 211 else
donatien 0:013f5d54248c 212 i--;
donatien 0:013f5d54248c 213 }
donatien 0:013f5d54248c 214 /* Timeout? */
donatien 0:013f5d54248c 215 if (i == 0)
donatien 0:013f5d54248c 216 return ERR_TIMEOUT;
donatien 0:013f5d54248c 217
donatien 0:013f5d54248c 218 /* Setup link based on configuration options */
donatien 0:013f5d54248c 219 #if PHY_USE_AUTONEG==1
donatien 0:013f5d54248c 220 tmp = DP8_AUTONEG;
donatien 0:013f5d54248c 221 #else
donatien 0:013f5d54248c 222 tmp = 0;
donatien 0:013f5d54248c 223 #endif
donatien 0:013f5d54248c 224 #if PHY_USE_100MBS==1
donatien 0:013f5d54248c 225 tmp |= DP8_SPEED_SELECT;
donatien 0:013f5d54248c 226 #endif
donatien 0:013f5d54248c 227 #if PHY_USE_FULL_DUPLEX==1
donatien 0:013f5d54248c 228 tmp |= DP8_DUPLEX_MODE;
donatien 0:013f5d54248c 229 #endif
donatien 0:013f5d54248c 230 lpc_mii_write(DP8_BMCR_REG, tmp);
donatien 0:013f5d54248c 231
donatien 0:013f5d54248c 232 /* The link is not set active at this point, but will be detected
donatien 0:013f5d54248c 233 later */
donatien 0:013f5d54248c 234
donatien 0:013f5d54248c 235 return ERR_OK;
donatien 0:013f5d54248c 236 }
donatien 0:013f5d54248c 237
donatien 0:013f5d54248c 238 /* Phy status update state machine */
donatien 0:013f5d54248c 239 s32_t lpc_phy_sts_sm(struct netif *netif)
donatien 0:013f5d54248c 240 {
donatien 0:013f5d54248c 241 s32_t changed = 0;
donatien 0:013f5d54248c 242
donatien 0:013f5d54248c 243 switch (phyustate) {
donatien 0:013f5d54248c 244 default:
donatien 0:013f5d54248c 245 case 0:
donatien 0:013f5d54248c 246 /* Read BMSR to clear faults */
donatien 0:013f5d54248c 247 lpc_mii_read_noblock(DP8_PHY_STAT_REG);
donatien 0:013f5d54248c 248 phyustate = 1;
donatien 0:013f5d54248c 249 break;
donatien 0:013f5d54248c 250
donatien 0:013f5d54248c 251 case 1:
donatien 0:013f5d54248c 252 /* Wait for read status state */
donatien 0:013f5d54248c 253 if (!lpc_mii_is_busy()) {
donatien 0:013f5d54248c 254 /* Update PHY status */
donatien 0:013f5d54248c 255 changed = lpc_update_phy_sts(netif, lpc_mii_read_data());
donatien 0:013f5d54248c 256 phyustate = 0;
donatien 0:013f5d54248c 257 }
donatien 0:013f5d54248c 258 break;
donatien 0:013f5d54248c 259 }
donatien 0:013f5d54248c 260
donatien 0:013f5d54248c 261 return changed;
donatien 0:013f5d54248c 262 }
donatien 0:013f5d54248c 263
donatien 0:013f5d54248c 264 /**
donatien 0:013f5d54248c 265 * @}
donatien 0:013f5d54248c 266 */
donatien 0:013f5d54248c 267
donatien 0:013f5d54248c 268 /* --------------------------------- End Of File ------------------------------ */