fdsf

Dependents:   sisk_proj_stat MQTT Hello_FXOS8700Q WireFSHandControl ... more

Committer:
grzemich
Date:
Wed Dec 07 23:47:50 2016 +0000
Revision:
0:d7bd7384a37c
dgd

Who changed what in which revision?

UserRevisionLine numberNew contents of line
grzemich 0:d7bd7384a37c 1 /**********************************************************************
grzemich 0:d7bd7384a37c 2 * $Id$ lpc_phy_dp83848.c 2011-11-20
grzemich 0:d7bd7384a37c 3 *//**
grzemich 0:d7bd7384a37c 4 * @file lpc_phy_dp83848.c
grzemich 0:d7bd7384a37c 5 * @brief DP83848C PHY status and control.
grzemich 0:d7bd7384a37c 6 * @version 1.0
grzemich 0:d7bd7384a37c 7 * @date 20 Nov. 2011
grzemich 0:d7bd7384a37c 8 * @author NXP MCU SW Application Team
grzemich 0:d7bd7384a37c 9 *
grzemich 0:d7bd7384a37c 10 * Copyright(C) 2011, NXP Semiconductor
grzemich 0:d7bd7384a37c 11 * All rights reserved.
grzemich 0:d7bd7384a37c 12 *
grzemich 0:d7bd7384a37c 13 ***********************************************************************
grzemich 0:d7bd7384a37c 14 * Software that is described herein is for illustrative purposes only
grzemich 0:d7bd7384a37c 15 * which provides customers with programming information regarding the
grzemich 0:d7bd7384a37c 16 * products. This software is supplied "AS IS" without any warranties.
grzemich 0:d7bd7384a37c 17 * NXP Semiconductors assumes no responsibility or liability for the
grzemich 0:d7bd7384a37c 18 * use of the software, conveys no license or title under any patent,
grzemich 0:d7bd7384a37c 19 * copyright, or mask work right to the product. NXP Semiconductors
grzemich 0:d7bd7384a37c 20 * reserves the right to make changes in the software without
grzemich 0:d7bd7384a37c 21 * notification. NXP Semiconductors also make no representation or
grzemich 0:d7bd7384a37c 22 * warranty that such application will be suitable for the specified
grzemich 0:d7bd7384a37c 23 * use without further testing or modification.
grzemich 0:d7bd7384a37c 24 **********************************************************************/
grzemich 0:d7bd7384a37c 25
grzemich 0:d7bd7384a37c 26 #include "lwip/opt.h"
grzemich 0:d7bd7384a37c 27 #include "lwip/err.h"
grzemich 0:d7bd7384a37c 28 #include "lwip/tcpip.h"
grzemich 0:d7bd7384a37c 29 #include "lwip/snmp.h"
grzemich 0:d7bd7384a37c 30 #include "lpc_emac_config.h"
grzemich 0:d7bd7384a37c 31 #include "lpc_phy.h"
grzemich 0:d7bd7384a37c 32 #include "lpc17xx_emac.h"
grzemich 0:d7bd7384a37c 33
grzemich 0:d7bd7384a37c 34 /** @defgroup dp83848_phy PHY status and control for the DP83848.
grzemich 0:d7bd7384a37c 35 * @ingroup lwip_phy
grzemich 0:d7bd7384a37c 36 *
grzemich 0:d7bd7384a37c 37 * Various functions for controlling and monitoring the status of the
grzemich 0:d7bd7384a37c 38 * DP83848 PHY. In polled (standalone) systems, the PHY state must be
grzemich 0:d7bd7384a37c 39 * monitored as part of the application. In a threaded (RTOS) system,
grzemich 0:d7bd7384a37c 40 * the PHY state is monitored by the PHY handler thread. The MAC
grzemich 0:d7bd7384a37c 41 * driver will not transmit unless the PHY link is active.
grzemich 0:d7bd7384a37c 42 * @{
grzemich 0:d7bd7384a37c 43 */
grzemich 0:d7bd7384a37c 44
grzemich 0:d7bd7384a37c 45 /** \brief DP83848 PHY register offsets */
grzemich 0:d7bd7384a37c 46 #define DP8_BMCR_REG 0x0 /**< Basic Mode Control Register */
grzemich 0:d7bd7384a37c 47 #define DP8_BMSR_REG 0x1 /**< Basic Mode Status Reg */
grzemich 0:d7bd7384a37c 48 #define DP8_IDR1_REG 0x2 /**< Basic Mode Status Reg */
grzemich 0:d7bd7384a37c 49 #define DP8_IDR2_REG 0x3 /**< Basic Mode Status Reg */
grzemich 0:d7bd7384a37c 50 #define DP8_ANADV_REG 0x4 /**< Auto_Neg Advt Reg */
grzemich 0:d7bd7384a37c 51 #define DP8_ANLPA_REG 0x5 /**< Auto_neg Link Partner Ability Reg */
grzemich 0:d7bd7384a37c 52 #define DP8_ANEEXP_REG 0x6 /**< Auto-neg Expansion Reg */
grzemich 0:d7bd7384a37c 53 #define DP8_PHY_STAT_REG 0x10 /**< PHY Status Register */
grzemich 0:d7bd7384a37c 54 #define DP8_PHY_INT_CTL_REG 0x11 /**< PHY Interrupt Control Register */
grzemich 0:d7bd7384a37c 55 #define DP8_PHY_RBR_REG 0x17 /**< PHY RMII and Bypass Register */
grzemich 0:d7bd7384a37c 56 #define DP8_PHY_STS_REG 0x19 /**< PHY Status Register */
grzemich 0:d7bd7384a37c 57
grzemich 0:d7bd7384a37c 58 #define DP8_PHY_SCSR_REG 0x1f /**< PHY Special Control/Status Register (LAN8720) */
grzemich 0:d7bd7384a37c 59
grzemich 0:d7bd7384a37c 60 /** \brief DP83848 Control register definitions */
grzemich 0:d7bd7384a37c 61 #define DP8_RESET (1 << 15) /**< 1= S/W Reset */
grzemich 0:d7bd7384a37c 62 #define DP8_LOOPBACK (1 << 14) /**< 1=loopback Enabled */
grzemich 0:d7bd7384a37c 63 #define DP8_SPEED_SELECT (1 << 13) /**< 1=Select 100MBps */
grzemich 0:d7bd7384a37c 64 #define DP8_AUTONEG (1 << 12) /**< 1=Enable auto-negotiation */
grzemich 0:d7bd7384a37c 65 #define DP8_POWER_DOWN (1 << 11) /**< 1=Power down PHY */
grzemich 0:d7bd7384a37c 66 #define DP8_ISOLATE (1 << 10) /**< 1=Isolate PHY */
grzemich 0:d7bd7384a37c 67 #define DP8_RESTART_AUTONEG (1 << 9) /**< 1=Restart auto-negoatiation */
grzemich 0:d7bd7384a37c 68 #define DP8_DUPLEX_MODE (1 << 8) /**< 1=Full duplex mode */
grzemich 0:d7bd7384a37c 69 #define DP8_COLLISION_TEST (1 << 7) /**< 1=Perform collsion test */
grzemich 0:d7bd7384a37c 70
grzemich 0:d7bd7384a37c 71 /** \brief DP83848 Status register definitions */
grzemich 0:d7bd7384a37c 72 #define DP8_100BASE_T4 (1 << 15) /**< T4 mode */
grzemich 0:d7bd7384a37c 73 #define DP8_100BASE_TX_FD (1 << 14) /**< 100MBps full duplex */
grzemich 0:d7bd7384a37c 74 #define DP8_100BASE_TX_HD (1 << 13) /**< 100MBps half duplex */
grzemich 0:d7bd7384a37c 75 #define DP8_10BASE_T_FD (1 << 12) /**< 100Bps full duplex */
grzemich 0:d7bd7384a37c 76 #define DP8_10BASE_T_HD (1 << 11) /**< 10MBps half duplex */
grzemich 0:d7bd7384a37c 77 #define DP8_MF_PREAMB_SUPPR (1 << 6) /**< Preamble suppress */
grzemich 0:d7bd7384a37c 78 #define DP8_AUTONEG_COMP (1 << 5) /**< Auto-negotation complete */
grzemich 0:d7bd7384a37c 79 #define DP8_RMT_FAULT (1 << 4) /**< Fault */
grzemich 0:d7bd7384a37c 80 #define DP8_AUTONEG_ABILITY (1 << 3) /**< Auto-negotation supported */
grzemich 0:d7bd7384a37c 81 #define DP8_LINK_STATUS (1 << 2) /**< 1=Link active */
grzemich 0:d7bd7384a37c 82 #define DP8_JABBER_DETECT (1 << 1) /**< Jabber detect */
grzemich 0:d7bd7384a37c 83 #define DP8_EXTEND_CAPAB (1 << 0) /**< Supports extended capabilities */
grzemich 0:d7bd7384a37c 84
grzemich 0:d7bd7384a37c 85 /** \brief DP83848 PHY RBR MII dode definitions */
grzemich 0:d7bd7384a37c 86 #define DP8_RBR_RMII_MODE (1 << 5) /**< Use RMII mode */
grzemich 0:d7bd7384a37c 87
grzemich 0:d7bd7384a37c 88 /** \brief DP83848 PHY status definitions */
grzemich 0:d7bd7384a37c 89 #define DP8_REMOTEFAULT (1 << 6) /**< Remote fault */
grzemich 0:d7bd7384a37c 90 #define DP8_FULLDUPLEX (1 << 2) /**< 1=full duplex */
grzemich 0:d7bd7384a37c 91 #define DP8_SPEED10MBPS (1 << 1) /**< 1=10MBps speed */
grzemich 0:d7bd7384a37c 92 #define DP8_VALID_LINK (1 << 0) /**< 1=Link active */
grzemich 0:d7bd7384a37c 93
grzemich 0:d7bd7384a37c 94 /** \brief DP83848 PHY ID register definitions */
grzemich 0:d7bd7384a37c 95 #define DP8_PHYID1_OUI 0x2000 /**< Expected PHY ID1 */
grzemich 0:d7bd7384a37c 96 #define DP8_PHYID2_OUI 0x5c90 /**< Expected PHY ID2 */
grzemich 0:d7bd7384a37c 97
grzemich 0:d7bd7384a37c 98 /** \brief LAN8720 PHY Special Control/Status Register */
grzemich 0:d7bd7384a37c 99 #define PHY_SCSR_100MBIT 0x0008 /**< Speed: 1=100 MBit, 0=10Mbit */
grzemich 0:d7bd7384a37c 100 #define PHY_SCSR_DUPLEX 0x0010 /**< PHY Duplex Mask */
grzemich 0:d7bd7384a37c 101
grzemich 0:d7bd7384a37c 102 /** \brief Link status bits */
grzemich 0:d7bd7384a37c 103 #define LNK_STAT_VALID 0x01
grzemich 0:d7bd7384a37c 104 #define LNK_STAT_FULLDUPLEX 0x02
grzemich 0:d7bd7384a37c 105 #define LNK_STAT_SPEED10MPS 0x04
grzemich 0:d7bd7384a37c 106
grzemich 0:d7bd7384a37c 107 /** \brief PHY ID definitions */
grzemich 0:d7bd7384a37c 108 #define DP83848C_ID 0x20005C90 /**< PHY Identifier - DP83848C */
grzemich 0:d7bd7384a37c 109 #define LAN8720_ID 0x0007C0F0 /**< PHY Identifier - LAN8720 */
grzemich 0:d7bd7384a37c 110
grzemich 0:d7bd7384a37c 111 /** \brief PHY status structure used to indicate current status of PHY.
grzemich 0:d7bd7384a37c 112 */
grzemich 0:d7bd7384a37c 113 typedef struct {
grzemich 0:d7bd7384a37c 114 u32_t phy_speed_100mbs:1; /**< 10/100 MBS connection speed flag. */
grzemich 0:d7bd7384a37c 115 u32_t phy_full_duplex:1; /**< Half/full duplex connection speed flag. */
grzemich 0:d7bd7384a37c 116 u32_t phy_link_active:1; /**< Phy link active flag. */
grzemich 0:d7bd7384a37c 117 } PHY_STATUS_TYPE;
grzemich 0:d7bd7384a37c 118
grzemich 0:d7bd7384a37c 119 /** \brief PHY update flags */
grzemich 0:d7bd7384a37c 120 static PHY_STATUS_TYPE physts;
grzemich 0:d7bd7384a37c 121
grzemich 0:d7bd7384a37c 122 /** \brief Last PHY update flags, used for determing if something has changed */
grzemich 0:d7bd7384a37c 123 static PHY_STATUS_TYPE olddphysts;
grzemich 0:d7bd7384a37c 124
grzemich 0:d7bd7384a37c 125 /** \brief PHY update counter for state machine */
grzemich 0:d7bd7384a37c 126 static s32_t phyustate;
grzemich 0:d7bd7384a37c 127
grzemich 0:d7bd7384a37c 128 /** \brief Holds the PHY ID */
grzemich 0:d7bd7384a37c 129 static u32_t phy_id;
grzemich 0:d7bd7384a37c 130
grzemich 0:d7bd7384a37c 131 /** \brief Temporary holder of link status for LAN7420 */
grzemich 0:d7bd7384a37c 132 static u32_t phy_lan7420_sts_tmp;
grzemich 0:d7bd7384a37c 133
grzemich 0:d7bd7384a37c 134 /* Write a value via the MII link (non-blocking) */
grzemich 0:d7bd7384a37c 135 void lpc_mii_write_noblock(u32_t PhyReg, u32_t Value)
grzemich 0:d7bd7384a37c 136 {
grzemich 0:d7bd7384a37c 137 /* Write value at PHY address and register */
grzemich 0:d7bd7384a37c 138 LPC_EMAC->MADR = (LPC_PHYDEF_PHYADDR << 8) | PhyReg;
grzemich 0:d7bd7384a37c 139 LPC_EMAC->MWTD = Value;
grzemich 0:d7bd7384a37c 140 }
grzemich 0:d7bd7384a37c 141
grzemich 0:d7bd7384a37c 142 /* Write a value via the MII link (blocking) */
grzemich 0:d7bd7384a37c 143 err_t lpc_mii_write(u32_t PhyReg, u32_t Value)
grzemich 0:d7bd7384a37c 144 {
grzemich 0:d7bd7384a37c 145 u32_t mst = 250;
grzemich 0:d7bd7384a37c 146 err_t sts = ERR_OK;
grzemich 0:d7bd7384a37c 147
grzemich 0:d7bd7384a37c 148 /* Write value at PHY address and register */
grzemich 0:d7bd7384a37c 149 lpc_mii_write_noblock(PhyReg, Value);
grzemich 0:d7bd7384a37c 150
grzemich 0:d7bd7384a37c 151 /* Wait for unbusy status */
grzemich 0:d7bd7384a37c 152 while (mst > 0) {
grzemich 0:d7bd7384a37c 153 sts = LPC_EMAC->MIND;
grzemich 0:d7bd7384a37c 154 if ((sts & EMAC_MIND_BUSY) == 0)
grzemich 0:d7bd7384a37c 155 mst = 0;
grzemich 0:d7bd7384a37c 156 else {
grzemich 0:d7bd7384a37c 157 mst--;
grzemich 0:d7bd7384a37c 158 osDelay(1);
grzemich 0:d7bd7384a37c 159 }
grzemich 0:d7bd7384a37c 160 }
grzemich 0:d7bd7384a37c 161
grzemich 0:d7bd7384a37c 162 if (sts != 0)
grzemich 0:d7bd7384a37c 163 sts = ERR_TIMEOUT;
grzemich 0:d7bd7384a37c 164
grzemich 0:d7bd7384a37c 165 return sts;
grzemich 0:d7bd7384a37c 166 }
grzemich 0:d7bd7384a37c 167
grzemich 0:d7bd7384a37c 168 /* Reads current MII link busy status */
grzemich 0:d7bd7384a37c 169 u32_t lpc_mii_is_busy(void)
grzemich 0:d7bd7384a37c 170 {
grzemich 0:d7bd7384a37c 171 return (u32_t) (LPC_EMAC->MIND & EMAC_MIND_BUSY);
grzemich 0:d7bd7384a37c 172 }
grzemich 0:d7bd7384a37c 173
grzemich 0:d7bd7384a37c 174 /* Starts a read operation via the MII link (non-blocking) */
grzemich 0:d7bd7384a37c 175 u32_t lpc_mii_read_data(void)
grzemich 0:d7bd7384a37c 176 {
grzemich 0:d7bd7384a37c 177 u32_t data = LPC_EMAC->MRDD;
grzemich 0:d7bd7384a37c 178 LPC_EMAC->MCMD = 0;
grzemich 0:d7bd7384a37c 179
grzemich 0:d7bd7384a37c 180 return data;
grzemich 0:d7bd7384a37c 181 }
grzemich 0:d7bd7384a37c 182
grzemich 0:d7bd7384a37c 183 /* Starts a read operation via the MII link (non-blocking) */
grzemich 0:d7bd7384a37c 184 void lpc_mii_read_noblock(u32_t PhyReg)
grzemich 0:d7bd7384a37c 185 {
grzemich 0:d7bd7384a37c 186 /* Read value at PHY address and register */
grzemich 0:d7bd7384a37c 187 LPC_EMAC->MADR = (LPC_PHYDEF_PHYADDR << 8) | PhyReg;
grzemich 0:d7bd7384a37c 188 LPC_EMAC->MCMD = EMAC_MCMD_READ;
grzemich 0:d7bd7384a37c 189 }
grzemich 0:d7bd7384a37c 190
grzemich 0:d7bd7384a37c 191 /* Read a value via the MII link (blocking) */
grzemich 0:d7bd7384a37c 192 err_t lpc_mii_read(u32_t PhyReg, u32_t *data)
grzemich 0:d7bd7384a37c 193 {
grzemich 0:d7bd7384a37c 194 u32_t mst = 250;
grzemich 0:d7bd7384a37c 195 err_t sts = ERR_OK;
grzemich 0:d7bd7384a37c 196
grzemich 0:d7bd7384a37c 197 /* Read value at PHY address and register */
grzemich 0:d7bd7384a37c 198 lpc_mii_read_noblock(PhyReg);
grzemich 0:d7bd7384a37c 199
grzemich 0:d7bd7384a37c 200 /* Wait for unbusy status */
grzemich 0:d7bd7384a37c 201 while (mst > 0) {
grzemich 0:d7bd7384a37c 202 sts = LPC_EMAC->MIND & ~EMAC_MIND_MII_LINK_FAIL;
grzemich 0:d7bd7384a37c 203 if ((sts & EMAC_MIND_BUSY) == 0) {
grzemich 0:d7bd7384a37c 204 mst = 0;
grzemich 0:d7bd7384a37c 205 *data = LPC_EMAC->MRDD;
grzemich 0:d7bd7384a37c 206 } else {
grzemich 0:d7bd7384a37c 207 mst--;
grzemich 0:d7bd7384a37c 208 osDelay(1);
grzemich 0:d7bd7384a37c 209 }
grzemich 0:d7bd7384a37c 210 }
grzemich 0:d7bd7384a37c 211
grzemich 0:d7bd7384a37c 212 LPC_EMAC->MCMD = 0;
grzemich 0:d7bd7384a37c 213
grzemich 0:d7bd7384a37c 214 if (sts != 0)
grzemich 0:d7bd7384a37c 215 sts = ERR_TIMEOUT;
grzemich 0:d7bd7384a37c 216
grzemich 0:d7bd7384a37c 217 return sts;
grzemich 0:d7bd7384a37c 218 }
grzemich 0:d7bd7384a37c 219
grzemich 0:d7bd7384a37c 220
grzemich 0:d7bd7384a37c 221
grzemich 0:d7bd7384a37c 222 /** \brief Update PHY status from passed value
grzemich 0:d7bd7384a37c 223 *
grzemich 0:d7bd7384a37c 224 * This function updates the current PHY status based on the
grzemich 0:d7bd7384a37c 225 * passed PHY status word. The PHY status indicate if the link
grzemich 0:d7bd7384a37c 226 * is active, the connection speed, and duplex.
grzemich 0:d7bd7384a37c 227 *
grzemich 0:d7bd7384a37c 228 * \param[in] netif NETIF structure
grzemich 0:d7bd7384a37c 229 * \param[in] linksts Status word from PHY
grzemich 0:d7bd7384a37c 230 * \return 1 if the status has changed, otherwise 0
grzemich 0:d7bd7384a37c 231 */
grzemich 0:d7bd7384a37c 232 static s32_t lpc_update_phy_sts(struct netif *netif, u32_t linksts)
grzemich 0:d7bd7384a37c 233 {
grzemich 0:d7bd7384a37c 234 s32_t changed = 0;
grzemich 0:d7bd7384a37c 235
grzemich 0:d7bd7384a37c 236 /* Update link active status */
grzemich 0:d7bd7384a37c 237 if (linksts & LNK_STAT_VALID)
grzemich 0:d7bd7384a37c 238 physts.phy_link_active = 1;
grzemich 0:d7bd7384a37c 239 else
grzemich 0:d7bd7384a37c 240 physts.phy_link_active = 0;
grzemich 0:d7bd7384a37c 241
grzemich 0:d7bd7384a37c 242 /* Full or half duplex */
grzemich 0:d7bd7384a37c 243 if (linksts & LNK_STAT_FULLDUPLEX)
grzemich 0:d7bd7384a37c 244 physts.phy_full_duplex = 1;
grzemich 0:d7bd7384a37c 245 else
grzemich 0:d7bd7384a37c 246 physts.phy_full_duplex = 0;
grzemich 0:d7bd7384a37c 247
grzemich 0:d7bd7384a37c 248 /* Configure 100MBit/10MBit mode. */
grzemich 0:d7bd7384a37c 249 if (linksts & LNK_STAT_SPEED10MPS)
grzemich 0:d7bd7384a37c 250 physts.phy_speed_100mbs = 0;
grzemich 0:d7bd7384a37c 251 else
grzemich 0:d7bd7384a37c 252 physts.phy_speed_100mbs = 1;
grzemich 0:d7bd7384a37c 253
grzemich 0:d7bd7384a37c 254 if (physts.phy_speed_100mbs != olddphysts.phy_speed_100mbs) {
grzemich 0:d7bd7384a37c 255 changed = 1;
grzemich 0:d7bd7384a37c 256 if (physts.phy_speed_100mbs) {
grzemich 0:d7bd7384a37c 257 /* 100MBit mode. */
grzemich 0:d7bd7384a37c 258 lpc_emac_set_speed(1);
grzemich 0:d7bd7384a37c 259
grzemich 0:d7bd7384a37c 260 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
grzemich 0:d7bd7384a37c 261 }
grzemich 0:d7bd7384a37c 262 else {
grzemich 0:d7bd7384a37c 263 /* 10MBit mode. */
grzemich 0:d7bd7384a37c 264 lpc_emac_set_speed(0);
grzemich 0:d7bd7384a37c 265
grzemich 0:d7bd7384a37c 266 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
grzemich 0:d7bd7384a37c 267 }
grzemich 0:d7bd7384a37c 268
grzemich 0:d7bd7384a37c 269 olddphysts.phy_speed_100mbs = physts.phy_speed_100mbs;
grzemich 0:d7bd7384a37c 270 }
grzemich 0:d7bd7384a37c 271
grzemich 0:d7bd7384a37c 272 if (physts.phy_full_duplex != olddphysts.phy_full_duplex) {
grzemich 0:d7bd7384a37c 273 changed = 1;
grzemich 0:d7bd7384a37c 274 if (physts.phy_full_duplex)
grzemich 0:d7bd7384a37c 275 lpc_emac_set_duplex(1);
grzemich 0:d7bd7384a37c 276 else
grzemich 0:d7bd7384a37c 277 lpc_emac_set_duplex(0);
grzemich 0:d7bd7384a37c 278
grzemich 0:d7bd7384a37c 279 olddphysts.phy_full_duplex = physts.phy_full_duplex;
grzemich 0:d7bd7384a37c 280 }
grzemich 0:d7bd7384a37c 281
grzemich 0:d7bd7384a37c 282 if (physts.phy_link_active != olddphysts.phy_link_active) {
grzemich 0:d7bd7384a37c 283 changed = 1;
grzemich 0:d7bd7384a37c 284 #if NO_SYS == 1
grzemich 0:d7bd7384a37c 285 if (physts.phy_link_active)
grzemich 0:d7bd7384a37c 286 netif_set_link_up(netif);
grzemich 0:d7bd7384a37c 287 else
grzemich 0:d7bd7384a37c 288 netif_set_link_down(netif);
grzemich 0:d7bd7384a37c 289 #else
grzemich 0:d7bd7384a37c 290 if (physts.phy_link_active)
grzemich 0:d7bd7384a37c 291 tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up,
grzemich 0:d7bd7384a37c 292 (void*) netif, 1);
grzemich 0:d7bd7384a37c 293 else
grzemich 0:d7bd7384a37c 294 tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down,
grzemich 0:d7bd7384a37c 295 (void*) netif, 1);
grzemich 0:d7bd7384a37c 296 #endif
grzemich 0:d7bd7384a37c 297
grzemich 0:d7bd7384a37c 298 olddphysts.phy_link_active = physts.phy_link_active;
grzemich 0:d7bd7384a37c 299 }
grzemich 0:d7bd7384a37c 300
grzemich 0:d7bd7384a37c 301 return changed;
grzemich 0:d7bd7384a37c 302 }
grzemich 0:d7bd7384a37c 303
grzemich 0:d7bd7384a37c 304 /** \brief Initialize the DP83848 PHY.
grzemich 0:d7bd7384a37c 305 *
grzemich 0:d7bd7384a37c 306 * This function initializes the DP83848 PHY. It will block until
grzemich 0:d7bd7384a37c 307 * complete. This function is called as part of the EMAC driver
grzemich 0:d7bd7384a37c 308 * initialization. Configuration of the PHY at startup is
grzemich 0:d7bd7384a37c 309 * controlled by setting up configuration defines in lpc_phy.h.
grzemich 0:d7bd7384a37c 310 *
grzemich 0:d7bd7384a37c 311 * \param[in] netif NETIF structure
grzemich 0:d7bd7384a37c 312 * \param[in] rmii If set, configures the PHY for RMII mode
grzemich 0:d7bd7384a37c 313 * \return ERR_OK if the setup was successful, otherwise ERR_TIMEOUT
grzemich 0:d7bd7384a37c 314 */
grzemich 0:d7bd7384a37c 315 err_t lpc_phy_init(struct netif *netif, int rmii)
grzemich 0:d7bd7384a37c 316 {
grzemich 0:d7bd7384a37c 317 u32_t tmp;
grzemich 0:d7bd7384a37c 318 s32_t i;
grzemich 0:d7bd7384a37c 319
grzemich 0:d7bd7384a37c 320 physts.phy_speed_100mbs = olddphysts.phy_speed_100mbs = 0;
grzemich 0:d7bd7384a37c 321 physts.phy_full_duplex = olddphysts.phy_full_duplex = 0;
grzemich 0:d7bd7384a37c 322 physts.phy_link_active = olddphysts.phy_link_active = 0;
grzemich 0:d7bd7384a37c 323 phyustate = 0;
grzemich 0:d7bd7384a37c 324
grzemich 0:d7bd7384a37c 325 /* Only first read and write are checked for failure */
grzemich 0:d7bd7384a37c 326 /* Put the DP83848C in reset mode and wait for completion */
grzemich 0:d7bd7384a37c 327 if (lpc_mii_write(DP8_BMCR_REG, DP8_RESET) != 0)
grzemich 0:d7bd7384a37c 328 return ERR_TIMEOUT;
grzemich 0:d7bd7384a37c 329 i = 400;
grzemich 0:d7bd7384a37c 330 while (i > 0) {
grzemich 0:d7bd7384a37c 331 osDelay(1); /* 1 ms */
grzemich 0:d7bd7384a37c 332 if (lpc_mii_read(DP8_BMCR_REG, &tmp) != 0)
grzemich 0:d7bd7384a37c 333 return ERR_TIMEOUT;
grzemich 0:d7bd7384a37c 334
grzemich 0:d7bd7384a37c 335 if (!(tmp & (DP8_RESET | DP8_POWER_DOWN)))
grzemich 0:d7bd7384a37c 336 i = -1;
grzemich 0:d7bd7384a37c 337 else
grzemich 0:d7bd7384a37c 338 i--;
grzemich 0:d7bd7384a37c 339 }
grzemich 0:d7bd7384a37c 340 /* Timeout? */
grzemich 0:d7bd7384a37c 341 if (i == 0)
grzemich 0:d7bd7384a37c 342 return ERR_TIMEOUT;
grzemich 0:d7bd7384a37c 343
grzemich 0:d7bd7384a37c 344 // read PHY ID
grzemich 0:d7bd7384a37c 345 lpc_mii_read(DP8_IDR1_REG, &tmp);
grzemich 0:d7bd7384a37c 346 phy_id = (tmp << 16);
grzemich 0:d7bd7384a37c 347 lpc_mii_read(DP8_IDR2_REG, &tmp);
grzemich 0:d7bd7384a37c 348 phy_id |= (tmp & 0XFFF0);
grzemich 0:d7bd7384a37c 349
grzemich 0:d7bd7384a37c 350 /* Setup link based on configuration options */
grzemich 0:d7bd7384a37c 351 #if PHY_USE_AUTONEG==1
grzemich 0:d7bd7384a37c 352 tmp = DP8_AUTONEG;
grzemich 0:d7bd7384a37c 353 #else
grzemich 0:d7bd7384a37c 354 tmp = 0;
grzemich 0:d7bd7384a37c 355 #endif
grzemich 0:d7bd7384a37c 356 #if PHY_USE_100MBS==1
grzemich 0:d7bd7384a37c 357 tmp |= DP8_SPEED_SELECT;
grzemich 0:d7bd7384a37c 358 #endif
grzemich 0:d7bd7384a37c 359 #if PHY_USE_FULL_DUPLEX==1
grzemich 0:d7bd7384a37c 360 tmp |= DP8_DUPLEX_MODE;
grzemich 0:d7bd7384a37c 361 #endif
grzemich 0:d7bd7384a37c 362 lpc_mii_write(DP8_BMCR_REG, tmp);
grzemich 0:d7bd7384a37c 363
grzemich 0:d7bd7384a37c 364 /* Enable RMII mode for PHY */
grzemich 0:d7bd7384a37c 365 if (rmii)
grzemich 0:d7bd7384a37c 366 lpc_mii_write(DP8_PHY_RBR_REG, DP8_RBR_RMII_MODE);
grzemich 0:d7bd7384a37c 367
grzemich 0:d7bd7384a37c 368 /* The link is not set active at this point, but will be detected
grzemich 0:d7bd7384a37c 369 later */
grzemich 0:d7bd7384a37c 370
grzemich 0:d7bd7384a37c 371 return ERR_OK;
grzemich 0:d7bd7384a37c 372 }
grzemich 0:d7bd7384a37c 373
grzemich 0:d7bd7384a37c 374 /* Phy status update state machine */
grzemich 0:d7bd7384a37c 375 s32_t lpc_phy_sts_sm(struct netif *netif)
grzemich 0:d7bd7384a37c 376 {
grzemich 0:d7bd7384a37c 377 s32_t changed = 0;
grzemich 0:d7bd7384a37c 378 u32_t data = 0;
grzemich 0:d7bd7384a37c 379 u32_t tmp;
grzemich 0:d7bd7384a37c 380
grzemich 0:d7bd7384a37c 381 switch (phyustate) {
grzemich 0:d7bd7384a37c 382 default:
grzemich 0:d7bd7384a37c 383 case 0:
grzemich 0:d7bd7384a37c 384 if (phy_id == DP83848C_ID) {
grzemich 0:d7bd7384a37c 385 lpc_mii_read_noblock(DP8_PHY_STAT_REG);
grzemich 0:d7bd7384a37c 386 phyustate = 2;
grzemich 0:d7bd7384a37c 387 }
grzemich 0:d7bd7384a37c 388 else if (phy_id == LAN8720_ID) {
grzemich 0:d7bd7384a37c 389 lpc_mii_read_noblock(DP8_PHY_SCSR_REG);
grzemich 0:d7bd7384a37c 390 phyustate = 1;
grzemich 0:d7bd7384a37c 391 }
grzemich 0:d7bd7384a37c 392 break;
grzemich 0:d7bd7384a37c 393
grzemich 0:d7bd7384a37c 394 case 1:
grzemich 0:d7bd7384a37c 395 if (phy_id == LAN8720_ID) {
grzemich 0:d7bd7384a37c 396 tmp = lpc_mii_read_data();
grzemich 0:d7bd7384a37c 397 // we get speed and duplex here.
grzemich 0:d7bd7384a37c 398 phy_lan7420_sts_tmp = (tmp & PHY_SCSR_DUPLEX) ? LNK_STAT_FULLDUPLEX : 0;
grzemich 0:d7bd7384a37c 399 phy_lan7420_sts_tmp |= (tmp & PHY_SCSR_100MBIT) ? 0 : LNK_STAT_SPEED10MPS;
grzemich 0:d7bd7384a37c 400
grzemich 0:d7bd7384a37c 401 //read the status register to get link status
grzemich 0:d7bd7384a37c 402 lpc_mii_read_noblock(DP8_BMSR_REG);
grzemich 0:d7bd7384a37c 403 phyustate = 2;
grzemich 0:d7bd7384a37c 404 }
grzemich 0:d7bd7384a37c 405 break;
grzemich 0:d7bd7384a37c 406
grzemich 0:d7bd7384a37c 407 case 2:
grzemich 0:d7bd7384a37c 408 /* Wait for read status state */
grzemich 0:d7bd7384a37c 409 if (!lpc_mii_is_busy()) {
grzemich 0:d7bd7384a37c 410 /* Update PHY status */
grzemich 0:d7bd7384a37c 411 tmp = lpc_mii_read_data();
grzemich 0:d7bd7384a37c 412
grzemich 0:d7bd7384a37c 413 if (phy_id == DP83848C_ID) {
grzemich 0:d7bd7384a37c 414 // STS register contains all needed status bits
grzemich 0:d7bd7384a37c 415 data = (tmp & DP8_VALID_LINK) ? LNK_STAT_VALID : 0;
grzemich 0:d7bd7384a37c 416 data |= (tmp & DP8_FULLDUPLEX) ? LNK_STAT_FULLDUPLEX : 0;
grzemich 0:d7bd7384a37c 417 data |= (tmp & DP8_SPEED10MBPS) ? LNK_STAT_SPEED10MPS : 0;
grzemich 0:d7bd7384a37c 418 }
grzemich 0:d7bd7384a37c 419 else if (phy_id == LAN8720_ID) {
grzemich 0:d7bd7384a37c 420 // we only get the link status here.
grzemich 0:d7bd7384a37c 421 phy_lan7420_sts_tmp |= (tmp & DP8_LINK_STATUS) ? LNK_STAT_VALID : 0;
grzemich 0:d7bd7384a37c 422 data = phy_lan7420_sts_tmp;
grzemich 0:d7bd7384a37c 423 }
grzemich 0:d7bd7384a37c 424
grzemich 0:d7bd7384a37c 425 changed = lpc_update_phy_sts(netif, data);
grzemich 0:d7bd7384a37c 426 phyustate = 0;
grzemich 0:d7bd7384a37c 427 }
grzemich 0:d7bd7384a37c 428 break;
grzemich 0:d7bd7384a37c 429 }
grzemich 0:d7bd7384a37c 430
grzemich 0:d7bd7384a37c 431 return changed;
grzemich 0:d7bd7384a37c 432 }
grzemich 0:d7bd7384a37c 433
grzemich 0:d7bd7384a37c 434 /**
grzemich 0:d7bd7384a37c 435 * @}
grzemich 0:d7bd7384a37c 436 */
grzemich 0:d7bd7384a37c 437
grzemich 0:d7bd7384a37c 438 /* --------------------------------- End Of File ------------------------------ */