a test code to implement and test LP1768 power control mode

Dependencies:   mbed

This code implemented some LP1768 power mode : Sleep(), DeepSleep(), PowerDown(), DeepPowerDown(), BOGD_PowerDown(). It also has a test code to test these power modes and wakeup using watch dog. The wakeup part is based on Erik's code but add implementation for LP1768. As LP1768 has debug enabled in default, it cannot be waked up in DeepSleep mode. Therefore this code use WDC reset to wake up the chips from deep sleep. The test code also allow test the power under two clock frequency (96 MHz and 48MHz). Inspired by Paul and Michael Wang, I also tested the power reduction by power off PHY. The analysis could be found in http://mbed.org/users/steniu01/notebook/lp1768-power-mode-implementation-and-measurement-/#

Committer:
steniu01
Date:
Thu Jul 24 08:53:44 2014 +0000
Revision:
1:571258908570
Parent:
0:5c4169623549
demo version ;

Who changed what in which revision?

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