EthernetPowerControl

Dependencies:   mbed

Fork of PowerControl by Michael Wei

Committer:
abraha2d
Date:
Tue Oct 09 00:14:42 2018 +0000
Revision:
1:8d381ef0ebcc
Parent:
PowerControl/EthernetPowerControl.cpp@0:9bd5f1bdb845
Save point

Who changed what in which revision?

UserRevisionLine numberNew contents of line
no2chem 0:9bd5f1bdb845 1 #include "EthernetPowerControl.h"
no2chem 0:9bd5f1bdb845 2
no2chem 0:9bd5f1bdb845 3 static void write_PHY (unsigned int PhyReg, unsigned short Value) {
no2chem 0:9bd5f1bdb845 4 /* Write a data 'Value' to PHY register 'PhyReg'. */
no2chem 0:9bd5f1bdb845 5 unsigned int tout;
no2chem 0:9bd5f1bdb845 6 /* Hardware MII Management for LPC176x devices. */
no2chem 0:9bd5f1bdb845 7 LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
no2chem 0:9bd5f1bdb845 8 LPC_EMAC->MWTD = Value;
no2chem 0:9bd5f1bdb845 9
no2chem 0:9bd5f1bdb845 10 /* Wait utill operation completed */
no2chem 0:9bd5f1bdb845 11 for (tout = 0; tout < MII_WR_TOUT; tout++) {
no2chem 0:9bd5f1bdb845 12 if ((LPC_EMAC->MIND & MIND_BUSY) == 0) {
no2chem 0:9bd5f1bdb845 13 break;
no2chem 0:9bd5f1bdb845 14 }
no2chem 0:9bd5f1bdb845 15 }
no2chem 0:9bd5f1bdb845 16 }
no2chem 0:9bd5f1bdb845 17
no2chem 0:9bd5f1bdb845 18 static unsigned short read_PHY (unsigned int PhyReg) {
no2chem 0:9bd5f1bdb845 19 /* Read a PHY register 'PhyReg'. */
no2chem 0:9bd5f1bdb845 20 unsigned int tout, val;
no2chem 0:9bd5f1bdb845 21
no2chem 0:9bd5f1bdb845 22 LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
no2chem 0:9bd5f1bdb845 23 LPC_EMAC->MCMD = MCMD_READ;
no2chem 0:9bd5f1bdb845 24
no2chem 0:9bd5f1bdb845 25 /* Wait until operation completed */
no2chem 0:9bd5f1bdb845 26 for (tout = 0; tout < MII_RD_TOUT; tout++) {
no2chem 0:9bd5f1bdb845 27 if ((LPC_EMAC->MIND & MIND_BUSY) == 0) {
no2chem 0:9bd5f1bdb845 28 break;
no2chem 0:9bd5f1bdb845 29 }
no2chem 0:9bd5f1bdb845 30 }
no2chem 0:9bd5f1bdb845 31 LPC_EMAC->MCMD = 0;
no2chem 0:9bd5f1bdb845 32 val = LPC_EMAC->MRDD;
no2chem 0:9bd5f1bdb845 33
no2chem 0:9bd5f1bdb845 34 return (val);
no2chem 0:9bd5f1bdb845 35 }
no2chem 0:9bd5f1bdb845 36
no2chem 0:9bd5f1bdb845 37 void EMAC_Init()
no2chem 0:9bd5f1bdb845 38 {
no2chem 0:9bd5f1bdb845 39 unsigned int tout,regv;
no2chem 0:9bd5f1bdb845 40 /* Power Up the EMAC controller. */
no2chem 0:9bd5f1bdb845 41 Peripheral_PowerUp(LPC1768_PCONP_PCENET);
no2chem 0:9bd5f1bdb845 42
no2chem 0:9bd5f1bdb845 43 LPC_PINCON->PINSEL2 = 0x50150105;
no2chem 0:9bd5f1bdb845 44 LPC_PINCON->PINSEL3 &= ~0x0000000F;
no2chem 0:9bd5f1bdb845 45 LPC_PINCON->PINSEL3 |= 0x00000005;
no2chem 0:9bd5f1bdb845 46
no2chem 0:9bd5f1bdb845 47 /* Reset all EMAC internal modules. */
no2chem 0:9bd5f1bdb845 48 LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
no2chem 0:9bd5f1bdb845 49 MAC1_SIM_RES | MAC1_SOFT_RES;
no2chem 0:9bd5f1bdb845 50 LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;
no2chem 0:9bd5f1bdb845 51
no2chem 0:9bd5f1bdb845 52 /* A short delay after reset. */
no2chem 0:9bd5f1bdb845 53 for (tout = 100; tout; tout--);
no2chem 0:9bd5f1bdb845 54
no2chem 0:9bd5f1bdb845 55 /* Initialize MAC control registers. */
no2chem 0:9bd5f1bdb845 56 LPC_EMAC->MAC1 = MAC1_PASS_ALL;
no2chem 0:9bd5f1bdb845 57 LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
no2chem 0:9bd5f1bdb845 58 LPC_EMAC->MAXF = ETH_MAX_FLEN;
no2chem 0:9bd5f1bdb845 59 LPC_EMAC->CLRT = CLRT_DEF;
no2chem 0:9bd5f1bdb845 60 LPC_EMAC->IPGR = IPGR_DEF;
no2chem 0:9bd5f1bdb845 61
no2chem 0:9bd5f1bdb845 62 /* Enable Reduced MII interface. */
no2chem 0:9bd5f1bdb845 63 LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM;
no2chem 0:9bd5f1bdb845 64
no2chem 0:9bd5f1bdb845 65 /* Reset Reduced MII Logic. */
no2chem 0:9bd5f1bdb845 66 LPC_EMAC->SUPP = SUPP_RES_RMII;
no2chem 0:9bd5f1bdb845 67 for (tout = 100; tout; tout--);
no2chem 0:9bd5f1bdb845 68 LPC_EMAC->SUPP = 0;
no2chem 0:9bd5f1bdb845 69
no2chem 0:9bd5f1bdb845 70 /* Put the DP83848C in reset mode */
no2chem 0:9bd5f1bdb845 71 write_PHY (PHY_REG_BMCR, 0x8000);
no2chem 0:9bd5f1bdb845 72
no2chem 0:9bd5f1bdb845 73 /* Wait for hardware reset to end. */
no2chem 0:9bd5f1bdb845 74 for (tout = 0; tout < 0x100000; tout++) {
no2chem 0:9bd5f1bdb845 75 regv = read_PHY (PHY_REG_BMCR);
no2chem 0:9bd5f1bdb845 76 if (!(regv & 0x8000)) {
no2chem 0:9bd5f1bdb845 77 /* Reset complete */
no2chem 0:9bd5f1bdb845 78 break;
no2chem 0:9bd5f1bdb845 79 }
no2chem 0:9bd5f1bdb845 80 }
no2chem 0:9bd5f1bdb845 81 }
no2chem 0:9bd5f1bdb845 82
no2chem 0:9bd5f1bdb845 83
no2chem 0:9bd5f1bdb845 84 void PHY_PowerDown()
no2chem 0:9bd5f1bdb845 85 {
no2chem 0:9bd5f1bdb845 86 if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
no2chem 0:9bd5f1bdb845 87 EMAC_Init(); //init EMAC if it is not already init'd
no2chem 0:9bd5f1bdb845 88
no2chem 0:9bd5f1bdb845 89 unsigned int regv;
no2chem 0:9bd5f1bdb845 90 regv = read_PHY(PHY_REG_BMCR);
no2chem 0:9bd5f1bdb845 91 write_PHY(PHY_REG_BMCR, regv | (1 << PHY_REG_BMCR_POWERDOWN));
no2chem 0:9bd5f1bdb845 92 regv = read_PHY(PHY_REG_BMCR);
no2chem 0:9bd5f1bdb845 93
no2chem 0:9bd5f1bdb845 94 //shouldn't need the EMAC now.
no2chem 0:9bd5f1bdb845 95 Peripheral_PowerDown(LPC1768_PCONP_PCENET);
no2chem 0:9bd5f1bdb845 96
no2chem 0:9bd5f1bdb845 97 //and turn off the PHY OSC
no2chem 0:9bd5f1bdb845 98 LPC_GPIO1->FIODIR |= 0x8000000;
no2chem 0:9bd5f1bdb845 99 LPC_GPIO1->FIOCLR = 0x8000000;
no2chem 0:9bd5f1bdb845 100 }
no2chem 0:9bd5f1bdb845 101
no2chem 0:9bd5f1bdb845 102 void PHY_PowerUp()
no2chem 0:9bd5f1bdb845 103 {
no2chem 0:9bd5f1bdb845 104 if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
no2chem 0:9bd5f1bdb845 105 EMAC_Init(); //init EMAC if it is not already init'd
no2chem 0:9bd5f1bdb845 106
no2chem 0:9bd5f1bdb845 107 LPC_GPIO1->FIODIR |= 0x8000000;
no2chem 0:9bd5f1bdb845 108 LPC_GPIO1->FIOSET = 0x8000000;
no2chem 0:9bd5f1bdb845 109
no2chem 0:9bd5f1bdb845 110 //wait for osc to be stable
no2chem 0:9bd5f1bdb845 111 wait_ms(200);
no2chem 0:9bd5f1bdb845 112
no2chem 0:9bd5f1bdb845 113 unsigned int regv;
no2chem 0:9bd5f1bdb845 114 regv = read_PHY(PHY_REG_BMCR);
no2chem 0:9bd5f1bdb845 115 write_PHY(PHY_REG_BMCR, regv & ~(1 << PHY_REG_BMCR_POWERDOWN));
no2chem 0:9bd5f1bdb845 116 regv = read_PHY(PHY_REG_BMCR);
no2chem 0:9bd5f1bdb845 117 }
no2chem 0:9bd5f1bdb845 118
no2chem 0:9bd5f1bdb845 119 void PHY_EnergyDetect_Enable()
no2chem 0:9bd5f1bdb845 120 {
no2chem 0:9bd5f1bdb845 121 if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
no2chem 0:9bd5f1bdb845 122 EMAC_Init(); //init EMAC if it is not already init'd
no2chem 0:9bd5f1bdb845 123
no2chem 0:9bd5f1bdb845 124 unsigned int regv;
no2chem 0:9bd5f1bdb845 125 regv = read_PHY(PHY_REG_EDCR);
no2chem 0:9bd5f1bdb845 126 write_PHY(PHY_REG_BMCR, regv | (1 << PHY_REG_EDCR_ENABLE));
no2chem 0:9bd5f1bdb845 127 regv = read_PHY(PHY_REG_EDCR);
no2chem 0:9bd5f1bdb845 128 }
no2chem 0:9bd5f1bdb845 129
no2chem 0:9bd5f1bdb845 130 void PHY_EnergyDetect_Disable()
no2chem 0:9bd5f1bdb845 131 {
no2chem 0:9bd5f1bdb845 132 if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
no2chem 0:9bd5f1bdb845 133 EMAC_Init(); //init EMAC if it is not already init'd
no2chem 0:9bd5f1bdb845 134 unsigned int regv;
no2chem 0:9bd5f1bdb845 135 regv = read_PHY(PHY_REG_EDCR);
no2chem 0:9bd5f1bdb845 136 write_PHY(PHY_REG_BMCR, regv & ~(1 << PHY_REG_EDCR_ENABLE));
no2chem 0:9bd5f1bdb845 137 regv = read_PHY(PHY_REG_EDCR);
no2chem 0:9bd5f1bdb845 138 }