├── dp83640ptp1588.h ├── readme.md ├── dp83640cfg1588.h ├── dp83640ptp1588.c ├── dp83640cfg1588.c ├── epl_regs.h └── MainDemo.c /dp83640ptp1588.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_DP83640PTP1588_H 2 | #define INCLUDE_DP83640PTP1588_H 3 | 4 | #include // BOOL 5 | 6 | void PTPEthInit(); 7 | void PTPSendSync(); 8 | void PTPProcess(); 9 | // use it to broadcast timestamps on the wire 10 | void PTPSendPDelayResp(unsigned int seconds, unsigned int nanoSeconds, BOOL master); 11 | BOOL Debug(char * msg); 12 | 13 | long long TimeFuse(unsigned int seconds, unsigned int ns); 14 | int TimeSeconds(long long time); 15 | int TimeNanoSeconds(long long time); 16 | 17 | #endif -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | This project is an implementation of the Precision Time Protocol (IEEE 1588 v2) for Microchip PIC32MX MCUs. It is used to synchronize time between two DP83640 PHYs (network cards) connected directly to each other via an ethernet cable. The project depends on the legacy (2012) Microchip TCP/IP stack. 2 | 3 | dp83640ptp1588.c - my code related to IEEE 1588 v2 (PTP). 4 | dp83640ptp1588.h - function definitions from dp83640ptp1588.c 5 | epl_regs.h - National Semiconductor Corporation's DP83640 PHY register definitions. 6 | dp83640cfg1588.c - National Semiconductor Corporation's epl_1588.c (heavily modified). 7 | dp83640cfg1588.h - function definitions from dp83640cfg1588.c 8 | MainDemo.c - Part of microchip's Application Library from which everything is called. 9 | 10 | MainDemo.c is a mess. It contains hooks for all of Microchips's network demo code. Unfortunately this is what I got. Look for function names starting with PTP*. 11 | 12 | Code ?MIGHT? depend on modifications in one of the following headers: "ETHPIC32ExtPhy.h", "configs/HWP PIC32_ETH_SK_ETH795.h", I remember some protocol id had to be changed from 8 bit to 16 bit somewhere... 13 | -------------------------------------------------------------------------------- /dp83640cfg1588.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_DP83640CFG1588_H 2 | #define INCLUDE_DP83640CFG1588_H 3 | 4 | #include // BOOL, UINT32 5 | #include "epl_regs.h" 6 | 7 | // P640_ZZZ are defined in epl_regs.h 8 | #define PTPEVT_TRANSMIT_TIMESTAMP_BIT P640_TXTS_RDY 9 | #define PTPEVT_RECEIVE_TIMESTAMP_BIT P640_RXTS_RDY 10 | #define PTPEVT_TRIGGER_DONE_BIT P640_TRIG_DONE 11 | #define PTPEVT_EVENT_TIMESTAMP_BIT P640_EVENT_RDY 12 | 13 | void PTPEnable(BOOL enableFlag); 14 | void PTPPulseOutEnable(BOOL enable); // temporary disable/enable 15 | void PTPPulseOutStart(); // periodic trigger 16 | void PTPClockOutEnable(BOOL enable, unsigned char divider); 17 | void PTPClockRead(unsigned int* seconds, unsigned int* nanoseconds); 18 | void PTPClockSet(unsigned int seconds, unsigned int nanoseconds); 19 | void PTPClockStepAdjustment(int seconds, int nanoseconds); 20 | 21 | unsigned int PTPCheckForEvents(); 22 | BOOL PTPGetEvent(unsigned int *eventBits, unsigned int *riseFlags, 23 | unsigned int *eventTimeSeconds, unsigned int *eventTimeNanoSeconds, unsigned int *eventsMissed); 24 | void PTPSetEventConfig (UINT event, BOOL eventRiseFlag, BOOL eventFallFlag, BOOL eventSingle, UINT gpioConnection); 25 | BOOL PTPGetTxTimestamp(unsigned int* seconds, unsigned int* nanoSeconds); 26 | BOOL PTPGetRxTimestamp(unsigned int* seconds, unsigned int* nanoSeconds); 27 | 28 | void PTPEnableDelayReqTimestampInsertion(BOOL enable); 29 | void PTPEnableSyncTimestampInsertion(BOOL enable_sync); 30 | void PTPConfigRxTimeInsert(); 31 | 32 | void EnableSynchronousEthernet(BOOL enable); 33 | 34 | #endif -------------------------------------------------------------------------------- /dp83640ptp1588.c: -------------------------------------------------------------------------------- 1 | #include // BYTE, WORD 2 | #include // memcpy() 3 | #include 4 | #include "configs/HWP PIC32_ETH_SK_ETH795.h" // LED1_IO 5 | #include "dp83640cfg1588.h" // PTPClockStepAdjustment() 6 | #include "dp83640ptp1588.h" 7 | 8 | 9 | // IEEE 1588 v2 frame definitions. 10 | typedef struct { 11 | unsigned char clockIdentity[8]; 12 | unsigned short portNumber; 13 | } PortIdentity; 14 | 15 | 16 | typedef struct { // Offset Length (bytes) 17 | unsigned char transportSpecificAndMessageType; // 00 1 (2 4-bit fields) 18 | unsigned char reservedAndVersionPTP; // 01 1 (2 4-bit fields) 19 | unsigned short messageLength; // 02 2 20 | unsigned char domainNumber; // 04 1 21 | unsigned char rxSeconds; // 05 1 // reserved - stores LSB of seconds receive timestamp inserted by DP83640 22 | unsigned char flags[2]; // 06 2 23 | long long correctionField; // 08 8 24 | unsigned int rxNanoSeconds; // 16 4 25 | PortIdentity sourcePortId; // 20 10 26 | unsigned short sequenceId; // 30 2 27 | unsigned char control; // 32 1 28 | unsigned char logMeanMessageInterval; // 33 1 29 | unsigned short txEpoch; // 34 2 // used in Sync, Delay_Req, Delay_Resp 30 | unsigned int txSeconds; // 36 4 // used in Sync, Delay_Req, Delay_Resp 31 | unsigned int txNanoSeconds; // 40 4 // used in Sync, Delay_Req, Delay_Resp 32 | PortIdentity requestingPortId; // 44 10 // used in Delay_Resp 33 | } Frame1588; 34 | 35 | 36 | #define PTP_MSG_SYNC 0 37 | #define PTP_MSG_DELAY_REQ 1 38 | #define PTP_MSG_PDELAY_RESP 3 39 | #define PTP_MSG_DELAY_RESP 9 40 | #define PTP_MSG_DELAY_RESP_CTL 3 41 | 42 | #define RX_TIMESTAMP_ADJUSTMENT (215) // ns for 100Base-TX as per PHYTER Dev Guide 43 | #define BILION (0x3B9ACA00ll) // long long not one one at the end! 44 | #define LOWER30BITS (0x3FFFFFFF) 45 | #define FRAME_TYPE_1588 (0x88F7) 46 | //#define ABS(x) (((x)>0)?(x):(-(x))) 47 | 48 | 49 | // copied from mac.h to avoid the include dependencies of mac.h and StackTsk.h 50 | typedef struct __attribute__((__packed__)){ BYTE v[6]; } MAC_ADDR; 51 | WORD MACGetArray(BYTE *val, WORD len); 52 | void MACPutArray(BYTE *val, WORD len); 53 | void MACPutHeader(MAC_ADDR *remote, WORD type, WORD dataLen); 54 | BOOL MACIsTxReady(void); 55 | BOOL MACIsLinked(); 56 | void MACFlush(void); 57 | 58 | // local prototypes 59 | void PTPSendDelayReq(); 60 | void PTPSendDelayResp(long long timeStamp); 61 | BOOL PTPSendFrame(); 62 | 63 | static Frame1588 inFrame; 64 | static Frame1588 outFrame; 65 | static MAC_ADDR remote_mac_addr = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; //broadcast 66 | 67 | //******************* Time Conversion ********************************* 68 | long long TimeFuse(unsigned int seconds, unsigned int ns){ 69 | // long long lsec, lns, ret; 70 | // lsec = seconds; 71 | // lns = ns; 72 | 73 | // ret = lsec*BILION; 74 | // ret+= lns; 75 | // return ret; 76 | return ((long long)seconds)*BILION + ((long long)ns); 77 | } 78 | 79 | int TimeSeconds(long long time){ 80 | // long long ret; 81 | // ret = time/BILION; 82 | // int retint; 83 | // retint = ret; 84 | // return retint; 85 | return ((long long)time)/BILION; 86 | } 87 | 88 | int TimeNanoSeconds(long long time){ 89 | // long long ret; 90 | // ret = time%BILION; 91 | // int retint; 92 | // retint = ret; 93 | // return retint; 94 | return ((long long)time) % BILION; 95 | } 96 | 97 | 98 | //******************* Synchronization ********************************* 99 | static long long time1, time2, avgRndTrip; 100 | 101 | void SyncAddT1T2(long long T1, long long T2){ 102 | time1 = T1; 103 | time2 = T2; 104 | } 105 | 106 | void SyncAddT3T4(long long time3, long long time4){ 107 | long long lastRoundTrip, deltaT; 108 | //TODO: incorporate RX_TIMESTAMP_ADJUSTMENT into calculations of t4 and t2??? 109 | 110 | // long long dt41,dt32,dt21,dt43; 111 | // dt41 = (time4-time1); 112 | // dt32 = (time3-time2); 113 | // dt21 = (time2-time1); 114 | // dt43 = (time4-time3); 115 | 116 | // if(dt41<0 || dt32<0){ 117 | // return; 118 | // } 119 | 120 | lastRoundTrip = (time4-time1)-(time3-time2); 121 | if(avgRndTrip){ 122 | // avgRndTrip = (avgRndTrip*31ll + lastRoundTrip ) / 32ll; 123 | avgRndTrip = (avgRndTrip*7ll + lastRoundTrip ) / 8ll; 124 | deltaT = time4 - time3 - avgRndTrip/2 +16; // +16 for the addition adjustment time 125 | PTPClockStepAdjustment(TimeSeconds(deltaT), TimeNanoSeconds(deltaT)); 126 | // char msg[128]; 127 | // sprintf(msg,"clock adjustment %us %uns", TimeSeconds(deltaT), TimeNanoSeconds(deltaT)); 128 | // Debug(msg); 129 | } else { 130 | avgRndTrip = lastRoundTrip; 131 | deltaT = time4+avgRndTrip/2ll; 132 | PTPClockSet( TimeSeconds(deltaT), TimeNanoSeconds(deltaT) ); 133 | } 134 | } 135 | 136 | 137 | //********************************************************************** 138 | // implementation will change if timestamp is appended 139 | long long GetPhyInsertedTime(Frame1588* frame){ 140 | unsigned int seconds, nanoSeconds; 141 | PTPClockRead(&seconds, &nanoSeconds); // need upper 3 bytes of seconds 142 | 143 | if( (seconds&0xFF) < frame->rxSeconds){ // second byte of seconds was incremented after timestamp was inserted 144 | seconds = htonl(ntohl(seconds)-256); // decrement 145 | } 146 | 147 | seconds = (seconds & 0xFFFFFF00) | frame->rxSeconds; 148 | nanoSeconds = ntohl(frame->rxNanoSeconds) & LOWER30BITS; 149 | 150 | long long ret; 151 | ret = TimeFuse(seconds, nanoSeconds); 152 | return ret; 153 | } 154 | 155 | 156 | void PTPEthInit(){ 157 | // make slave wait for Sync in PTPSend() 158 | inFrame.transportSpecificAndMessageType = PTP_MSG_DELAY_RESP; 159 | outFrame.reservedAndVersionPTP = 2; 160 | outFrame.messageLength = htons((unsigned short)sizeof(Frame1588)); 161 | } 162 | 163 | 164 | void PTPProcess(MAC_ADDR* remote){ 165 | int readBytes; 166 | readBytes = MACGetArray((BYTE*)&inFrame, sizeof(Frame1588)); 167 | 168 | // I am using a switch to test and can't sniff if the actuall mac is used 169 | //memcpy(&remote_mac_addr, remote, sizeof(MAC_ADDR)); // save remote MAC address 170 | 171 | long long timeStamp; 172 | timeStamp = GetPhyInsertedTime(&inFrame); 173 | // Delay_Req Timestamp was disabled and did not record the time 174 | if(!timeStamp){ return; } 175 | 176 | // send Delay_Resp right away 177 | if(inFrame.transportSpecificAndMessageType == PTP_MSG_DELAY_REQ){ 178 | return PTPSendDelayResp(timeStamp); 179 | } 180 | 181 | long long remoteTime; 182 | remoteTime = TimeFuse(ntohl(inFrame.txSeconds), ntohl(inFrame.txNanoSeconds)); 183 | 184 | if(inFrame.transportSpecificAndMessageType == PTP_MSG_SYNC){ 185 | SyncAddT1T2(remoteTime,timeStamp); 186 | PTPSendDelayReq(); // since we got Sync, we are in slave mode 187 | inFrame.transportSpecificAndMessageType = PTP_MSG_DELAY_RESP; // avoid sending multiple Delay_Req 188 | } else { // PTP_MSG_DELAY_RESP 189 | if(inFrame.sequenceId != outFrame.sequenceId){ 190 | return; // response is not for the latest request we sent out 191 | } 192 | SyncAddT3T4(timeStamp,remoteTime); 193 | } 194 | } 195 | 196 | void PTPSendSync(){ 197 | static unsigned short nextSequenceId; 198 | outFrame.transportSpecificAndMessageType = PTP_MSG_SYNC; 199 | outFrame.control = PTP_MSG_SYNC; 200 | outFrame.sequenceId = htons(++nextSequenceId); 201 | outFrame.txSeconds = 0; // will be inserted by DP83640 202 | outFrame.txNanoSeconds = 0; // will be inserted by DP83640 203 | PTPSendFrame(); 204 | } 205 | 206 | void PTPSendDelayReq(){ 207 | outFrame.transportSpecificAndMessageType = PTP_MSG_DELAY_REQ; 208 | outFrame.control = PTP_MSG_DELAY_REQ; 209 | outFrame.sequenceId = inFrame.sequenceId; // has to match for timestamps to be valid 210 | outFrame.txSeconds = 0; 211 | outFrame.txNanoSeconds = 0; 212 | PTPSendFrame(); 213 | } 214 | 215 | void PTPSendDelayResp(long long timeStamp){ 216 | outFrame.transportSpecificAndMessageType = PTP_MSG_DELAY_RESP; 217 | outFrame.control = PTP_MSG_DELAY_RESP_CTL; 218 | outFrame.sequenceId = inFrame.sequenceId; // has to match for timestamp to be valid 219 | outFrame.txSeconds = htonl(TimeSeconds(timeStamp)); 220 | outFrame.txNanoSeconds = htonl(TimeNanoSeconds(timeStamp)); 221 | PTPSendFrame(); 222 | } 223 | 224 | // use Debug instead 225 | //void PTPSendPDelayResp(unsigned int seconds, unsigned int nanoSeconds, BOOL master){ 226 | // static unsigned lastFrameSecondsValue; 227 | // if(seconds == lastFrameSecondsValue){ // debounce (1 event per second) 228 | // return; 229 | // } 230 | // lastFrameSecondsValue = seconds; 231 | // 232 | // outFrame.transportSpecificAndMessageType = PTP_MSG_PDELAY_RESP; 233 | // outFrame.control = PTP_MSG_DELAY_RESP_CTL; 234 | // outFrame.sequenceId = htons(master?0:1); 235 | // outFrame.txSeconds = htonl(seconds); 236 | // outFrame.txNanoSeconds = htonl(nanoSeconds); 237 | // PTPSendFrame(); 238 | //} 239 | 240 | // send ethernet frame header with type = 0x88F7 plus outFrame 241 | BOOL PTPSendFrame(){ 242 | if(! MACIsLinked() ){ return FALSE; } 243 | while(!MACIsTxReady()); //TODO: queue the frames? 244 | 245 | // size could change depending on the type of the frame ( TODO ) 246 | MACPutHeader(&remote_mac_addr, FRAME_TYPE_1588,sizeof(outFrame)); 247 | MACPutArray((BYTE*)&outFrame, sizeof(outFrame)); 248 | MACFlush(); 249 | return TRUE; 250 | } 251 | 252 | BOOL Debug(char * msg){ 253 | if(! MACIsLinked() ){ return FALSE; } 254 | while(!MACIsTxReady()); //TODO: queue the frames? 255 | 256 | unsigned int len; 257 | len = strlen(msg)+1; 258 | MACPutHeader(&remote_mac_addr, 0x7777, len); 259 | MACPutArray((BYTE*)msg, len); 260 | MACFlush(); 261 | return TRUE; 262 | } -------------------------------------------------------------------------------- /dp83640cfg1588.c: -------------------------------------------------------------------------------- 1 | //**************************************************************************** 2 | // epl_1588.c 3 | // 4 | // Copyright (c) 2007-2008 National Semiconductor Corporation. 5 | // All Rights Reserved 6 | // 7 | // Contains sources for IEEE 1588 related functions. 8 | // 9 | //**************************************************************************** 10 | 11 | // This file is heavily modified. See comments in original epl_1588.c for function descriptions 12 | #include 13 | #include 14 | #include "ETHPIC32ExtPhy.h" 15 | #include "epl_regs.h" 16 | #include "dp83640ptp1588.h" 17 | #include "dp83640cfg1588.h" 18 | 19 | // Adj for pin input delay and edge detection time (35ns = 8ns(refclk) * 4 + 3) 20 | #define PIN_INPUT_DELAY 35 21 | 22 | // Note: Bits [7:5] of rIx specify the register page (000-pg0, 001-pg1, 010-pg2, 011-pg3, etc.) 23 | unsigned short EPLReadReg(unsigned int rIx){ 24 | unsigned int phyAdd = EthPhyMIIMAddress(); 25 | EthMIIMWriteStart(PHY_PAGESEL, phyAdd, (rIx>>5)&7); // select proper page 26 | EthMIIMReadStart(rIx&0x1F, phyAdd); 27 | return EthMIIMReadResult(); 28 | } 29 | 30 | 31 | // Note: Bits [7:5] of rIx specify the register page (000-pg0, 001-pg1, 010-pg2, 011-pg3, etc.) 32 | void EPLWriteReg(unsigned int rIx, unsigned short wData){ 33 | unsigned int phyAdd = EthPhyMIIMAddress(); 34 | EthMIIMWriteStart(PHY_PAGESEL, phyAdd, (rIx>>5)&7); // select proper page 35 | while( EthMIIMBusy() ); 36 | EthMIIMWriteStart (rIx&0x1F, phyAdd, wData ); 37 | while( EthMIIMBusy() ); // wait for write to complete 38 | } 39 | 40 | 41 | void PTPEnable(BOOL enableFlag){ 42 | EPLWriteReg(PHY_PG4_PTP_CTL, enableFlag ? P640_PTP_ENABLE : P640_PTP_DISABLE); 43 | } 44 | 45 | 46 | void PTPClockRead(unsigned int* seconds, unsigned int* nanoSeconds){ 47 | EPLWriteReg(PHY_PG4_PTP_CTL, P640_PTP_RD_CLK); 48 | *nanoSeconds = EPLReadReg(PHY_PG4_PTP_TDR); 49 | *nanoSeconds |= EPLReadReg(PHY_PG4_PTP_TDR) << 16; 50 | *seconds = EPLReadReg(PHY_PG4_PTP_TDR); 51 | *seconds |= EPLReadReg(PHY_PG4_PTP_TDR) << 16; 52 | } 53 | 54 | 55 | void PTPClockSet(unsigned int seconds, unsigned int nanoSeconds){ 56 | PTPPulseOutEnable(FALSE); 57 | EPLWriteReg(PHY_PG4_PTP_TDR, nanoSeconds & 0xFFFF); 58 | EPLWriteReg(PHY_PG4_PTP_TDR, nanoSeconds >> 16); 59 | EPLWriteReg(PHY_PG4_PTP_TDR, seconds & 0xFFFF); 60 | EPLWriteReg(PHY_PG4_PTP_TDR, seconds >> 16); 61 | EPLWriteReg(PHY_PG4_PTP_CTL, P640_PTP_LOAD_CLK); 62 | PTPPulseOutStart(); 63 | } 64 | 65 | 66 | void PTPClockStepAdjustment(int seconds, int nanoSeconds){ 67 | PTPPulseOutEnable(FALSE); 68 | // TODO: adjust +16ns for the time it takes to add to the counter 69 | // nanoSeconds = htonl(ntohl(nanoSeconds)+16); // compensate for 2-cycle addition 70 | // if(abs(ntohl(nanoSeconds)) > 1000000000){ // did compensation rolled over 1 seconds mark? 71 | // nanoSeconds = htonl(ntohl(nanoSeconds)%1000000000); 72 | // seconds = htonl((ntohl(seconds)>0)? ntohl(seconds)+1 : ntohl(seconds)-1); 73 | // } 74 | 75 | // PTPPulseOutStart(); 76 | // return; // DEBUGGING! 77 | 78 | // nanoSeconds = (nanoSeconds > 0) ? htonl(8) : htonl(-8); 79 | 80 | // if(nanoSeconds &0x80000000){ // disable negative adjustments while DEBUGGING 81 | // nanoSeconds = -1000; 82 | // nanoSeconds = htons(nanoSeconds); 83 | // } 84 | 85 | EPLWriteReg(PHY_PG4_PTP_TDR, nanoSeconds & 0xFFFF); 86 | EPLWriteReg(PHY_PG4_PTP_TDR, nanoSeconds >> 16); 87 | EPLWriteReg(PHY_PG4_PTP_TDR, seconds & 0xFFFF); 88 | EPLWriteReg(PHY_PG4_PTP_TDR, seconds >> 16); 89 | EPLWriteReg(PHY_PG4_PTP_CTL, P640_PTP_STEP_CLK); 90 | PTPPulseOutStart(); 91 | } 92 | 93 | 94 | // enable insertion of the timestamp into Delay_Resp message 95 | // not mutually exclusive with PTPEnableSyncTimeStampInsertion() 96 | // registers: PTP_TXCFG0:DR_INSERT,SYNC_1STEP 97 | void PTPEnableDelayReqTimestampInsertion(BOOL enable){ 98 | unsigned short txcfg0; 99 | txcfg0 = EPLReadReg(PHY_PG5_PTP_TXCFG0) & 0x1FFF; 100 | EPLWriteReg(PHY_PG5_PTP_TXCFG0, (txcfg0&0x1FFF) | (enable?P640_DR_INSERT:P640_SYNC_1STEP) ); 101 | } 102 | 103 | // configures Transmit Timestamp Operation 104 | // registers involved in configuration: PTP_TXCFG0, PTP_TXCFG1 105 | void PTPEnableSyncTimestampInsertion(BOOL enable_sync){ 106 | EPLWriteReg(PHY_PG5_PTP_TXCFG0, (enable_sync?P640_SYNC_1STEP:P640_DR_INSERT)|P640_IGNORE_2STEP|P640_CRC_1STEP|P640_TX_L2_EN|P640_TX_TS_EN); // 107 | } 108 | 109 | // could use offsetof() macro in stddef.h 110 | #define RX_STAMP_NS_OFFSET (16<<6) // Frame1588.rxNanoSeconds into bits 11:6 111 | #define RX_STAMP_SEC_OFFSET (5) // Frame1588.rxSeconds 112 | #define TS_SEC_LEN (0<<12) // 00-LSB, 01-2LSBs, 10-3LSBs, 11-4bytes 113 | 114 | // configure receive timestamp insertion into the packet 115 | // registers PTP_RXCFG0, PTP_RXCFG1, PTP_RXCFG2, PTP_RXCFG3, PTP_RXCFG4 116 | void PTPConfigRxTimeInsert(){ 117 | EPLWriteReg(PHY_PG5_PTP_RXCFG0, P640_RX_L2_EN|P640_RX_TS_EN); 118 | EPLWriteReg(PHY_PG5_PTP_RXCFG3, P640_ACC_CRC|P640_TS_INSERT); 119 | EPLWriteReg(PHY_PG5_PTP_RXCFG4, P640_TS_SEC_EN|TS_SEC_LEN|RX_STAMP_NS_OFFSET|RX_STAMP_SEC_OFFSET); 120 | } 121 | 122 | 123 | /* 124 | # Example Configuration of the Output Clock: 125 | # Nominal Output Clock Frequency = 10 MHz (divide-by-25), 250 MHz Clock Source 126 | # 1. Write 0x8019 to PTP_COC 127 | # This enables the clock output using a divide-by-25 (0x19) from the 250 MHz FCO clock. 128 | PTP_COC = 0x14 # on page 6 129 | PAGESEL = 0x13 130 | extMod.WriteReg(PAGESEL,6) 131 | extMod.WriteReg(PTP_COC,0x8019) 132 | */ 133 | void PTPClockOutEnable(BOOL enable, unsigned char divider){ 134 | EPLWriteReg(PHY_PG6_PTP_COC, (enable?0x8000:0) |P640_PTP_CLKOUT_SPSEL|divider); 135 | } 136 | 137 | #define TRIGGER (0x0) 138 | #define TRIGGER_GPIO_PIN (0x3) 139 | #define PULSE_WIDTH (1000000ll) 140 | void PTPPulseOutStart(){ 141 | EPLWriteReg(PHY_PG5_PTP_TRIG,P640_TRIG_PER|(TRIGGER_GPIO_PIN<<8)|(TRIGGER<<1)|P640_TRIG_WR); //P640_TRIG_IF_LATE| 142 | 143 | unsigned int sec, ns; 144 | PTPClockRead(&sec,&ns); 145 | 146 | long long time; 147 | time = TimeFuse(sec,ns); 148 | // skip cycles but keep the edge aligned 149 | time = time/PULSE_WIDTH; 150 | time = time + 2ll; 151 | time = time * PULSE_WIDTH; 152 | // time = (2ll+(time/PULSE_WIDTH)) * PULSE_WIDTH; 153 | sec = TimeSeconds(time); 154 | ns = TimeNanoSeconds(time); 155 | 156 | EPLWriteReg(PHY_PG4_PTP_CTL, (TRIGGER<<10)|P640_TRIG_DIS|P640_TRIG_LOAD ); 157 | EPLWriteReg(PHY_PG4_PTP_TDR, ns & 0xFFFF); // start time ns lo 158 | EPLWriteReg(PHY_PG4_PTP_TDR, ns >> 16); // wait for seconds rollover | start time ns hi 159 | EPLWriteReg(PHY_PG4_PTP_TDR, sec & 0xFFFF); // start time sec 160 | EPLWriteReg(PHY_PG4_PTP_TDR, sec >>16); // start time sec 161 | EPLWriteReg(PHY_PG4_PTP_TDR, PULSE_WIDTH & 0xFFFF ); // pulse width lo 162 | EPLWriteReg(PHY_PG4_PTP_TDR, PULSE_WIDTH >> 16); // pulse width hi 163 | EPLWriteReg(PHY_PG4_PTP_TDR,0); // pulse width 2 lo 164 | EPLWriteReg(PHY_PG4_PTP_TDR,0); // pulse width 2 hi 165 | 166 | EPLWriteReg(PHY_PG4_PTP_CTL, (TRIGGER<<10)|P640_TRIG_EN ); 167 | } 168 | 169 | // PHYTER Software Development Guide page 20: 170 | // "If a large adjustment to the PTP time is made, the PPS trigger may need to be rearmed to avoid a long period of inactivity or a PEROD OF RAPID PULSING." 171 | void PTPPulseOutEnable(BOOL enable){ 172 | EPLWriteReg(PHY_PG4_PTP_CTL, (enable?P640_TRIG_EN:P640_TRIG_DIS)|(TRIGGER<<10) ); 173 | } 174 | 175 | 176 | 177 | void EnableSynchronousEthernet(BOOL enable){ 178 | unsigned short val; 179 | val = EPLReadReg(PHY_PG0_PHYCR2); 180 | EPLWriteReg(PHY_PG0_PHYCR2, (enable?PHYCR2_SYNC_ENET_EN:0) | val ); 181 | } 182 | 183 | 184 | BOOL PTPGetTxTimestamp(unsigned int* seconds, unsigned int* nanoSeconds){ 185 | if( !(P640_TXTS_RDY & EPLReadReg(PHY_PG4_PTP_STS)) ){ 186 | return FALSE; // no events 187 | } 188 | 189 | *nanoSeconds = EPLReadReg(PHY_PG4_PTP_TXTS); 190 | unsigned short reg; 191 | reg = EPLReadReg(PHY_PG4_PTP_TXTS); 192 | *nanoSeconds |= (reg & 0x3FFF) << 16; 193 | 194 | *seconds = EPLReadReg(PHY_PG4_PTP_TXTS); 195 | *seconds |= EPLReadReg(PHY_PG4_PTP_TXTS) << 16; 196 | return TRUE; 197 | } 198 | 199 | BOOL PTPGetRxTimestamp(unsigned int* seconds, unsigned int* nanoSeconds){ 200 | if( !(P640_RXTS_RDY & EPLReadReg(PHY_PG4_PTP_STS)) ){ 201 | return FALSE; // no events 202 | } 203 | 204 | unsigned short reg; 205 | 206 | *nanoSeconds = EPLReadReg(PHY_PG4_PTP_RXTS); 207 | reg = EPLReadReg(PHY_PG4_PTP_RXTS); 208 | // *overflowCount = (reg & 0xC000) >> 14; 209 | *nanoSeconds |= (reg & 0x3FFF) << 16; 210 | *seconds = EPLReadReg(PHY_PG4_PTP_RXTS); 211 | *seconds |= EPLReadReg(PHY_PG4_PTP_RXTS) << 16; 212 | // *sequenceId = 213 | EPLReadReg(PHY_PG4_PTP_RXTS); 214 | reg = EPLReadReg(PHY_PG4_PTP_RXTS); 215 | // *messageType = reg >> 12; 216 | // *hashValue = reg & 0x0FFF; 217 | return TRUE; 218 | } 219 | 220 | 221 | // Configures the operational behavior of an individual event. 222 | // event - The event to configure, 0 - 7. 223 | // eventRiseFlag 224 | // If set to TRUE, enables detection of rising edge on Event input. 225 | // eventFallFlag 226 | // If set to TRUE, enables detection of falling edge on Event input. 227 | // eventSingle 228 | // If set to TRUE, enables single event capture operation 229 | // gpioConnection 230 | // The GPIO pin the event should be connected to. A value of 0 - 12. 231 | // If 0 is specified no GPIO pin connection is made. 232 | void PTPSetEventConfig (UINT event, BOOL eventRiseFlag,BOOL eventFallFlag, 233 | BOOL eventSingle, UINT gpioConnection){ 234 | 235 | UINT reg; 236 | reg = 0; 237 | 238 | reg |= gpioConnection << P640_EVNT_GPIO_SHIFT; 239 | reg |= event << P640_EVNT_SEL_SHIFT; 240 | reg |= P640_EVNT_WR; 241 | EPLWriteReg(PHY_PG5_PTP_EVNT, reg); 242 | 243 | if ( eventRiseFlag) reg |= P640_EVNT_RISE; 244 | if ( eventFallFlag) reg |= P640_EVNT_FALL; 245 | if ( eventSingle) reg |= P640_EVNT_SINGLE; 246 | EPLWriteReg(PHY_PG5_PTP_EVNT, reg); 247 | return; 248 | } 249 | 250 | 251 | /* 252 | Enabling Event Monitoring 253 | For example, to enable event monitor 2 to monitor GPIO3 for rising edge detection: 254 | 1. Write 0x0305 to PTP_EVNT to select GPIO3 for event monitor 2. 255 | 2. Write 0x4305 to PTP_EVNT to enable event rise detection on GPIO3. 256 | 257 | The process for reading event timestamps is as follows: 258 | 1. Read PTP_ESTS to determine if an event timestamp is available. 259 | 2. Read from PTP_EDATA: Extended Event Status[15:0] (available only if PTP_ESTS:MULT_EVNT is set to 1) 260 | 3. Read from PTP_EDATA: Timestamp_ns[15:0] 261 | 4. Read from PTP_EDATA: Timestamp_ns[29:16] (upper 2 bits are always 0) 262 | 5. Read from PTP_EDATA: Timestamp_sec[15:0] 263 | 6. Read from PTP_EDATA: Timestamp_sec[31:16] 264 | 7. Repeat Steps 1-6 until PTP_ESTS = 0 265 | */ 266 | 267 | 268 | 269 | // Checks to determine if any of the following hardware events are 270 | // outstanding: Transmit timestamp, receive timestamp, trigger done and event 271 | // timestamp. 272 | // 273 | // Returns 274 | // A bit map of zero or more bits set indicating the types of events that 275 | // are available from the hardware. The defined bits are: 276 | // PTPEVT_TRANSMIT_TIMESTAMP_BIT 277 | // PTPEVT_RECEIVE_TIMESTAMP_BIT 278 | // PTPEVT_EVENT_TIMESTAMP_BIT 279 | // PTPEVT_TRIGGER_DONE_BIT 280 | // 281 | // This must be called prior to retrieving individual events from the 282 | // hardware. The bit map must be used to determine which "Get" functions 283 | // need to be called. The applicable "Get" functions are: 284 | // 285 | // PTPGetTransmitTimestamp 286 | // PTPGetReceiveTimestamp 287 | // PTPGetEvent 288 | // PTPHasTriggerExpired 289 | unsigned int PTPCheckForEvents(){ 290 | return EPLReadReg(PHY_PG4_PTP_STS) & (P640_TXTS_RDY|P640_RXTS_RDY|P640_TRIG_DONE|P640_EVENT_RDY); 291 | } 292 | 293 | 294 | // Returns the available asynchronous event timestamps. 295 | // 296 | // portHandle 297 | // Handle that represents a port. This is obtained using the EPLEnumPort 298 | // function. 299 | // eventBits 300 | // Set on return to a bit map of events that have occurred. Bit 0 is 301 | // event 0, etc. 0 or more bits may be set. 302 | // riseFlags 303 | // Set on return to a bit map indicating if an event occurred on the 304 | // rising edge (set to 1), or on the falling edge (set to 0). Bit 0 is 305 | // is the rising edge flag for event 0, etc. 306 | // eventTimeSeconds 307 | // The seconds portion of the IEEE 1588 clock timestamp when this event 308 | // occurred. 309 | // eventTimeNanoSeconds 310 | // The nanosecond portion of the IEEE 1588 clock timestamp when this 311 | // event occurred. This value will not be larger then 1e9 (1 second). 312 | // eventsMissed 313 | // Set on return to indicate the number of events that have been missed 314 | // prior to this event due to internal event queue overflow. The maximum 315 | // value is 7. 316 | // 317 | // Returns 318 | // TRUE if an event was returned, FALSE otherwise. 319 | // 320 | // The caller must have previously called PTPCheckForEvents() and determined 321 | // that the PTPEVT_EVET_TIMESTAMP_BIT bit was set prior to invoking this 322 | // function. This function does NOT check to determine if an outstanding 323 | // event is available. 324 | // 325 | // This function properly tracks and handles events that occur at the same 326 | // exact time. It also adjusts the timestamp values to compensate for input 327 | // path and synchronization delays. 328 | //**************************************************************************** 329 | BOOL PTPGetEvent(unsigned int *eventBits, unsigned int *riseFlags, 330 | unsigned int *eventTimeSeconds, unsigned int *eventTimeNanoSeconds, unsigned int *eventsMissed){ 331 | unsigned int reg, exSts, x; 332 | *eventBits = 0; 333 | *riseFlags = 0; 334 | 335 | reg = EPLReadReg(PHY_PG4_PTP_ESTS); 336 | *eventsMissed = (reg & P640_EVNTS_MISSED_MASK) >> P640_EVNTS_MISSED_SHIFT; 337 | if ( !(reg & P640_EVENT_DET)){ return FALSE; } 338 | 339 | if ( reg & P640_MULT_EVENT){ 340 | exSts = EPLReadReg(PHY_PG4_PTP_EDATA); 341 | for ( x = 8; x; x--){ 342 | if ( exSts & 0x40) 343 | *eventBits |= 1 << (x-1); 344 | if ( exSts & 0x80) 345 | *riseFlags |= 1 << (x-1); 346 | exSts <<= 2; 347 | } 348 | } else { 349 | *eventBits |= 1 << ((reg & P640_EVNT_NUM_MASK) >> P640_EVNT_NUM_SHIFT); 350 | *riseFlags |= ((reg & P640_EVNT_RF) ? 1 : 0) << ((reg & P640_EVNT_NUM_MASK) >> P640_EVNT_NUM_SHIFT); 351 | } 352 | 353 | *eventTimeNanoSeconds = EPLReadReg(PHY_PG4_PTP_EDATA); 354 | *eventTimeNanoSeconds |= EPLReadReg(PHY_PG4_PTP_EDATA) << 16; 355 | *eventTimeSeconds = EPLReadReg(PHY_PG4_PTP_EDATA); 356 | *eventTimeSeconds |= EPLReadReg(PHY_PG4_PTP_EDATA) << 16; 357 | 358 | // Adj for pin input delay and edge detection time 359 | if( *eventTimeNanoSeconds < PIN_INPUT_DELAY ){ 360 | if( *eventTimeSeconds > 0 ){ 361 | *eventTimeSeconds -= 1; 362 | *eventTimeNanoSeconds += ((unsigned int)1e9 - PIN_INPUT_DELAY); 363 | } else { 364 | *eventTimeSeconds = *eventTimeNanoSeconds = 0; 365 | } 366 | } else { 367 | *eventTimeNanoSeconds -= PIN_INPUT_DELAY; 368 | } 369 | return TRUE; 370 | } 371 | 372 | 373 | -------------------------------------------------------------------------------- /epl_regs.h: -------------------------------------------------------------------------------- 1 | //**************************************************************************** 2 | // epl_regs.h 3 | // 4 | // Copyright (c) 2006-2008 National Semiconductor Corporation. 5 | // All Rights Reserved 6 | // 7 | // This module defines all of the registers and fields available 8 | // in National Ethernet Phy devices. 9 | // 10 | // The following devices are described here: 11 | // DP83848, DP83849, DP83640 12 | //**************************************************************************** 13 | 14 | #ifndef _EPL_REGS_INCLUDE 15 | #define _EPL_REGS_INCLUDE 16 | 17 | 18 | // Phy Register Indexes - Common Across Device Types 19 | #define PHY_BMCR 0x0000 20 | #define PHY_BMSR 0x0001 21 | #define PHY_IDR1 0x0002 22 | #define PHY_IDR2 0x0003 23 | #define PHY_ANAR 0x0004 24 | #define PHY_ANLPAR 0x0005 25 | #define PHY_ANER 0x0006 26 | #define PHY_ANNPTR 0x0007 27 | #define PHY_PHYSTS 0x0010 28 | #define PHY_MICR 0x0011 29 | #define PHY_MISR 0x0012 30 | #define PHY_PAGESEL 0x0013 31 | #define PHY_FCSCR 0x0014 32 | #define PHY_RECR 0x0015 33 | #define PHY_PCSR 0x0016 34 | #define PHY_RBR 0x0017 35 | #define PHY_LEDCR 0x0018 36 | #define PHY_PHYCTRL 0x0019 37 | #define PHY_10BTSCR 0x001A 38 | #define PHY_CDCTRL1 0x001B 39 | #define PHY_EDCR 0x001D 40 | 41 | // DP83848 Specific Register Indexes 42 | #define PHY_AFECR 0x001E 43 | #define PHY_AFEAR 0x001F 44 | 45 | // DP83849 / DP83640 Specific Register Indexes 46 | // Note: Bits [6:5] specify the register page (00-pg0, 01-pg1, 10-pg2, 11-pg3) 47 | #define PHY_PG0_PHYCR2 0x001C 48 | #define PHY_PG1_PMDCNFG 0x0034 49 | #define PHY_PG1_TMR1 0x0035 50 | #define PHY_PG1_TMR2 0x0036 51 | #define PHY_PG1_DSP_CTRL1 0x0037 52 | #define PHY_PG1_DSP_CTRL2 0x0038 53 | #define PHY_PG1_TRL_CTRL 0x0039 54 | #define PHY_PG1_DEQ_CTRL 0x003A 55 | #define PHY_PG1_ANEG_TST 0x003B 56 | #define PHY_PG1_EXTCFG 0x003C 57 | #define PHY_PG1_TST_CTRL 0x003D 58 | #define PHY_PG1_SD_CNFG 0x003E 59 | #define PHY_PG1_TSTDAT 0x003F 60 | #define PHY_PG2_LEN100_DET 0x0054 61 | #define PHY_PG2_FREQ100 0x0055 62 | #define PHY_PG2_TDR_CTRL 0x0056 63 | #define PHY_PG2_TDR_WIN 0x0057 64 | #define PHY_PG2_TDR_PEAK 0x0058 65 | #define PHY_PG2_TDR_THR 0x0059 66 | #define PHY_PG2_VAR_CTRL 0x005A 67 | #define PHY_PG2_VAR_DATA 0x005B 68 | #define PHY_PG2_LQMR 0x005D 69 | #define PHY_PG2_LQDR 0x005E 70 | 71 | // DP83640 Specific Register Indexes 72 | // Note: Bits [7:5] specify the register page (000-pg0, 001-pg1, 010-pg2, 011-pg3, etc.) 73 | #define PHY_PG2_LQMR2 0x005F 74 | #define PHY_PG3_CGCR 0x0074 75 | #define PHY_PG3_PTPTR 0x0075 76 | #define PHY_PG3_CDCR1 0x0077 77 | #define PHY_PG3_CDCR2 0x0078 78 | #define PHY_PG3_FCO1CR 0x0079 79 | #define PHY_PG3_FCO2CR 0x007A 80 | #define PHY_PG3_ADCCR1 0x007B 81 | #define PHY_PG3_ADCCR2 0x007C 82 | #define PHY_PG3_BGREGCR 0x007D 83 | #define PHY_PG3_CGMCR 0x007E 84 | #define PHY_PG3_PGMCR 0x007F 85 | #define PHY_PG4_PTP_CTL 0x0094 86 | #define PHY_PG4_PTP_TDR 0x0095 87 | #define PHY_PG4_PTP_STS 0x0096 88 | #define PHY_PG4_PTP_TSTS 0x0097 89 | #define PHY_PG4_PTP_RATEL 0x0098 90 | #define PHY_PG4_PTP_RATEH 0x0099 91 | #define PHY_PG4_PTP_RDCKSUM 0x009A 92 | #define PHY_PG4_PTP_WRCKSUM 0x009B 93 | #define PHY_PG4_PTP_TXTS 0x009C 94 | #define PHY_PG4_PTP_RXTS 0x009D 95 | #define PHY_PG4_PTP_ESTS 0x009E 96 | #define PHY_PG4_PTP_EDATA 0x009F 97 | #define PHY_PG5_PTP_TRIG 0x00B4 98 | #define PHY_PG5_PTP_EVNT 0x00B5 99 | #define PHY_PG5_PTP_TXCFG0 0x00B6 100 | #define PHY_PG5_PTP_TXCFG1 0x00B7 101 | #define PHY_PG5_PSF_CFG0 0x00B8 102 | #define PHY_PG5_PTP_RXCFG0 0x00B9 103 | #define PHY_PG5_PTP_RXCFG1 0x00BA 104 | #define PHY_PG5_PTP_RXCFG2 0x00BB 105 | #define PHY_PG5_PTP_RXCFG3 0x00BC 106 | #define PHY_PG5_PTP_RXCFG4 0x00BD 107 | #define PHY_PG5_PTP_TRDL 0x00BE 108 | #define PHY_PG5_PTP_TRDH 0x00BF 109 | #define PHY_PG6_PTP_COC 0x00D4 110 | #define PHY_PG6_PSF_CFG1 0x00D5 111 | #define PHY_PG6_PSF_CFG2 0x00D6 112 | #define PHY_PG6_PSF_CFG3 0x00D7 113 | #define PHY_PG6_PSF_CFG4 0x00D8 114 | #define PHY_PG6_PTP_SFDCFG 0x00D9 115 | #define PHY_PG6_PTP_INTCTL 0x00DA 116 | #define PHY_PG6_PTP_CLKSRC 0x00DB 117 | #define PHY_PG6_PTP_ETR 0x00DC 118 | #define PHY_PG6_PTP_OFF 0x00DD 119 | #define PHY_PG6_PTP_GPIOMON 0x00DE 120 | #define PHY_PG6_PTP_RXHASH 0x00DF 121 | 122 | 123 | //**************************************************************************** 124 | // Common Register Bit Definitions 125 | //**************************************************************************** 126 | 127 | // PHY_BMCR Defs 128 | #define BMCR_FORCE_SPEED_1000 0x0040 129 | #define BMCR_COLLISION_TEST 0x0080 130 | #define BMCR_FORCE_FULL_DUP 0x0100 131 | #define BMCR_RESTART_AUTONEG 0x0200 132 | #define BMCR_ISOLATE 0x0400 133 | #define BMCR_POWER_DOWN 0x0800 134 | #define BMCR_AUTO_NEG_ENABLE 0x1000 135 | #define BMCR_FORCE_SPEED_100 0x2000 136 | #define BMCR_FORCE_SPEED_10 0x0000 137 | #define BMCR_FORCE_SPEED_MASK 0x2040 138 | #define BMCR_LOOPBACK 0x4000 139 | #define BMCR_RESET 0x8000 140 | 141 | // PHY_BMSR Defs 142 | #define BMSR_EXTENDED_CAPABLE 0x0001 143 | #define BMSR_JABBER_DETECT 0x0002 144 | #define BMSR_LINK_STATUS 0x0004 145 | #define BMSR_AUTO_NEG_ABILITY 0x0008 146 | #define BMSR_REMOTE_FAULT 0x0010 147 | #define BMSR_AUTO_NEG_COMPLETE 0x0020 148 | #define BMSR_PREAMBLE_SUPPRESS 0x0040 149 | #define BMSR_RESERVED 0x0080 150 | #define BMSR_1000T_EXT_STATUS 0x0100 151 | #define BMSR_100T2_HALF_DUP 0x0200 152 | #define BMSR_100T2_FULL_DUP 0x0400 153 | #define BMSR_10T_HALF_DUP 0x0800 154 | #define BMSR_10T_FULL_DUP 0x1000 155 | #define BMSR_100X_HALF_DUP 0x2000 156 | #define BMSR_100X_FULL_DUP 0x4000 157 | #define BMSR_100T4_CAPABLE 0x8000 158 | 159 | // PHY_IDR1 Defs 160 | #define IDR1_NATIONAL_OUI_VAL 0x2000 // OUI bits 3-18 161 | 162 | // PHY_IDR2 Defs 163 | #define IDR2_OUI_MASK 0xFC00 164 | #define IDR2_MODEL_NUMBER_MASK 0x03F0 165 | #define IDR2_REVISION_MASK 0x000F 166 | #define IDR2_MODEL_SHIFT 4 167 | 168 | #define IDR2_NATIONAL_OUI_VAL 0x5C00 // OUI bits 19-24 (15:10), Vendor Model (9:4), Revision (3:0) 169 | #define IDR2_MODEL_DP83848_VAL 0x0090 // AspenPhy 170 | #define IDR2_MODEL_DP48_MINI_VAL 0x00C0 // AspenPhy - Mini 171 | #define IDR2_MODEL_DP83849_VAL 0x00A0 // Dual AspenPhy 172 | #define IDR2_MODEL_DP83640_VAL 0x00E0 // High Precision Phy 173 | 174 | #define IDR2_REV_DP83848E_VAL 0x0001 // DP83848 Enhanced version 175 | 176 | // PHY_ANAR Defs 177 | #define ANAR_PROTO_SEL_MASK 0x001F 178 | #define ANAR_PROTO_8023 0x0001 179 | #define ANAR_10T_HALF_DUP 0x0020 180 | #define ANAR_10T_FULL_DUP 0x0040 181 | #define ANAR_100T_HALF_DUP 0x0080 182 | #define ANAR_100T_FULL_DUP 0x0100 183 | #define ANAR_100T4_SUPPORT 0x0200 184 | #define ANAR_PAUSE_SUPPORT 0x0400 185 | #define ANAR_ASY_PAUSE_SUPPORT 0x0800 186 | #define ANAR_RESERVED0 0x1000 187 | #define ANAR_REMOTE_FAULT 0x2000 188 | #define ANAR_RESERVED1 0x4000 189 | #define ANAR_NEXT_PAGE_IND 0x8000 190 | 191 | // PHY_ANLPAR Defs 192 | #define ANLPAR_PROTO_SEL_MASK 0x001F 193 | #define ANLPAR_10T_HALF_DUP 0x0020 194 | #define ANLPAR_10T_FULL_DUP 0x0040 195 | #define ANLPAR_100T_HALF_DUP 0x0080 196 | #define ANLPAR_100T_FULL_DUP 0x0100 197 | #define ANLPAR_100T4_SUPPORT 0x0200 198 | #define ANLPAR_PAUSE_SUPPORT 0x0400 199 | #define ANLPAR_ASY_PAUSE 0x0800 200 | #define ANLPAR_RESERVED0 0x1000 201 | #define ANLPAR_REMOTE_FAULT 0x2000 202 | #define ANLPAR_ACK 0x4000 203 | #define ANLPAR_NEXT_PAGE_IND 0x8000 204 | 205 | // PHY_ANER Defs 206 | #define ANER_AUTO_NEG_CAPABLE 0x0001 207 | #define ANER_PAGE_RX 0x0002 208 | #define ANER_NEXT_PAGE_ABLE 0x0004 209 | #define ANER_PRT_NEXT_PAGE_ABLE 0x0008 210 | #define ANER_PARALLEL_DET_FAULT 0x0010 211 | 212 | // PHY_ANNPTR Defs 213 | #define ANNPTR_CODE_MASK 0x07FF 214 | #define ANNPTR_TOGGLE 0x0800 215 | #define ANNPTR_ACK2 0x1000 216 | #define ANNPTR_MSG_PAGE 0x2000 217 | #define ANNPTR_ACK 0x4000 218 | #define ANNPTR_NEXT_PAGE_IND 0x8000 219 | 220 | 221 | //**************************************************************************** 222 | // DP83848 Specific Register Bit Definitions 223 | //**************************************************************************** 224 | 225 | // PHY_PHYSTS Defs 226 | #define P848_STS_LINK 0x0001 227 | #define P848_STS_SPEED 0x0002 228 | #define P848_STS_DUPLEX 0x0004 229 | #define P848_STS_LOOPBACK 0x0008 230 | #define P848_STS_AUTO_NEG_DONE 0x0010 231 | #define P848_STS_JABBER_DETECT 0x0020 232 | #define P848_STS_REMOTE_FAULT 0x0040 233 | #define P848_STS_MII_INTERRUPT 0x0080 234 | #define P848_STS_PAGE_RXED 0x0100 235 | #define P848_STS_DESCRAMBLER 0x0200 236 | #define P848_STS_SIGNAL_DETECT 0x0400 237 | #define P848_STS_FALSE_CARRIER 0x0800 238 | #define P848_STS_POLARITY 0x1000 239 | #define P848_STS_RX_ERROR_LATCH 0x2000 240 | #define P848_STS_MDIX_MODE 0x4000 241 | 242 | // PHY_MICR Defs 243 | #define P848_MICR_INTEN 0x0001 244 | #define P848_MICR_UNMSK_INT 0x0002 245 | #define P848_MICR_TINT 0x0004 246 | 247 | // PHY_MISR Defs 248 | #define P848_MISR_UNMSK_RHF 0x0001 249 | #define P848_MISR_UNMSK_FHF 0x0002 250 | #define P848_MISR_UNMSK_ANC 0x0004 251 | #define P848_MISR_UNMSK_RF 0x0008 252 | #define P848_MISR_UNMSK_JAB 0x0010 253 | #define P848_MISR_UNMSK_LINK 0x0020 254 | #define P848_MISR_UNMSK_ED 0x0040 255 | #define P848_MISR_MSK_RHF 0x0100 256 | #define P848_MISR_MSK_FHF 0x0200 257 | #define P848_MISR_MSK_ANC 0x0400 258 | #define P848_MISR_MSK_RF 0x0800 259 | #define P848_MISR_MSK_JAB 0x1000 260 | #define P848_MISR_MSK_LINK 0x2000 261 | #define P848_MISR_MSK_ED 0x4000 262 | 263 | // PHY_PAGESEL Defs 264 | #define P848_PAGESEL_PAGE_SEL 0x0001 265 | #define P848_PAGESEL_PAGE_0 0x0000 266 | #define P848_PAGESEL_PAGE_1 0x0001 267 | #define P848_PAGESEL_PAGE_2 0x0002 268 | #define P848_PAGESEL_PAGE_3 0x0003 269 | 270 | // PHY_FCSCR Defs 271 | #define P848_FCSCR_FCSCNT_MASK 0x00FF 272 | 273 | // PHY_RECR Defs 274 | #define P848_RECR_RXERRCNT_MASK 0x00FF 275 | 276 | // PHY_PCSR Defs 277 | #define P848_PCSR_DESCRAM_BYP 0x0001 278 | #define P848_PCSR_SCRAM_BYP 0x0002 279 | #define P848_PCSR_NRZI_BYP 0x0004 280 | #define P848_PCSR_FEFI_EN 0x0008 281 | #define P848_PCSR_FEFI_TST 0x0010 282 | #define P848_PCSR_FORCE_100_OK 0x0020 283 | #define P848_PCSR_FX_EN 0x0040 284 | #define P848_PCSR_SD_OPTION 0x0100 285 | #define P848_PCSR_SD_FORCE_PMA 0x0200 286 | #define P848_PCSR_TQ_EN 0x0400 287 | #define P848_PCSR_FREE_CLK 0x0800 288 | #define P848_PCSR_BYP_4B5B 0x1000 289 | 290 | // PHY_RBR Defs 291 | #define P848_RBR_RX_RD_4 0x0000 292 | #define P848_RBR_RX_RD_1 0x0001 293 | #define P848_RBR_RX_RD_2 0x0002 294 | #define P848_RBR_RX_RD_3 0x0003 295 | #define P848_RBR_RX_UNF_STS 0x0004 296 | #define P848_RBR_RX_OVF_STS 0x0008 297 | #define P848_RBR_RMII_REV1_0 0x0010 298 | #define P848_RBR_RMII_MODE 0x0020 299 | 300 | // PHY_LEDCR Defs 301 | #define P848_LED_ACTLED 0x0001 302 | #define P848_LED_LNKLED 0x0002 303 | #define P848_LED_SPDLED 0x0004 304 | #define P848_LED_DRV_ACTLED 0x0008 305 | #define P848_LED_DRV_LNKLED 0x0010 306 | #define P848_LED_DRV_SPDLED 0x0020 307 | 308 | // PHY_PHYCTRL Defs 309 | #define P848_PHYCTRL_ADDR_MASK 0x001F 310 | #define P848_PHYCTRL_LED_CFG0 0x0020 311 | #define P848_PHYCTRL_LED_CFG1 0x0040 312 | #define P848_PHYCTRL_BP_STRETCH 0x0080 313 | #define P848_PHYCTRL_BIST_START 0x0100 314 | #define P848_PHYCTRL_BIST_STS 0x0200 315 | #define P848_PHYCTRL_PSR_15 0x0400 316 | #define P848_PHYCTRL_BIST_FE 0x0800 317 | #define P848_PHYCTRL_PAUSE_TX 0x1000 318 | #define P848_PHYCTRL_PAUSE_RX 0x2000 319 | #define P848_PHYCTRL_FORCE_MDIX 0x4000 320 | #define P848_PHYCTRL_MDIX_EN 0x8000 321 | 322 | // PHY_10BTSCR Defs 323 | #define P848_10BTSCR_JABBER_DIS 0x0001 324 | #define P848_10BTSCR_HRTBT_DIS 0x0002 325 | #define P848_10BTSCR_SCALE_MSB 0x0004 326 | #define P848_10BTSCR_ATDIS 0x0008 327 | #define P848_10BTSCR_POLARITY 0x0010 328 | #define P848_10BTSCR_FORCEPOL 0x0020 329 | #define P848_10BTSCR_FRC_10 0x0040 330 | #define P848_10BTSCR_LP_DIS 0x0080 331 | #define P848_10BTSCR_LP_10_DIS 0x0100 332 | #define P848_10BTSCR_SQLCH_MASK 0x0E00 333 | #define P848_10BTSCR_ERRRG_MASK 0x3000 334 | #define P848_10BTSCR_REJECT100T 0x4000 335 | #define P848_10BTSCR_10BT_SER 0x8000 336 | 337 | // PHY_CDCTRL1 Defs 338 | #define P848_CDCTRL1_CDPATTSEL0 0x0001 339 | #define P848_CDCTRL1_CDPATTSEL1 0x0002 340 | #define P848_CDCTRL1_10MEG_PG 0x0004 341 | #define P848_CDCTRL1_CDPATTEN10 0x0010 342 | #define P848_CDCTRL1_BIST_CONT 0x0020 343 | #define P848_CDCTRL1_BIST_EC_MSK 0xFF00 344 | 345 | // PHY_EDCR Defs 346 | #define P848_EDCR_DATA_CNT_MASK 0x000F 347 | #define P848_EDCR_ERR_CNT_MASK 0x00F0 348 | #define P848_EDCR_DATA_MET 0x0100 349 | #define P848_EDCR_ERR_MET 0x0200 350 | #define P848_EDCR_PWR_STATE 0x0400 351 | #define P848_EDCR_BURST_DIS 0x0800 352 | #define P848_EDCR_MANUAL_POWER 0x1000 353 | #define P848_EDCR_AUTO_DOWN 0x2000 354 | #define P848_EDCR_AUTO_UP 0x4000 355 | #define P848_EDCR_ENABLE 0x8000 356 | 357 | //**************************************************************************** 358 | // DP83849 Dual Specific Register Bit Definitions 359 | //**************************************************************************** 360 | 361 | // PHY_RBR Defs Specific to this device 362 | #define P849_RBR_ELAST_BUF_MASK 0x0003 363 | #define P849_RBR_ELAST_14_BIT 0x0000 364 | #define P849_RBR_ELAST_2_BIT 0x0001 365 | #define P849_RBR_ELAST_6_BIT 0x0002 366 | #define P849_RBR_ELAST_10_BIT 0x0003 367 | #define P849_RBR_SINGLE_CLK_TX 0x0040 368 | #define P849_RBR_SINGLE_CLK_RX 0x0080 369 | #define P849_RBR_PMD_LOOP 0x0100 370 | #define P849_RBR_TX_SOURCE_MASK 0x0600 371 | #define P849_RBR_TX_NORMAL 0x0000 372 | #define P849_RBR_TX_OPPOSITE 0x0200 373 | #define P849_RBR_TX_OPPOSITE_RX 0x0400 374 | #define P849_RBR_TX_DISABLED 0x0600 375 | #define P849_RBR_RX_PORT_MASK 0x1800 376 | #define P849_RBR_RX_NORMAL 0x0000 377 | #define P849_RBR_RX_OPPOSITE 0x0800 378 | #define P849_RBR_RX_BOTH_PORTS 0x1000 379 | #define P849_RBR_RX_DISABLED 0x1800 380 | #define P849_RBR_DIS_TX_LAT_OPT 0x2000 381 | #define P849_RBR_SIM_WRITE_EN 0x8000 382 | 383 | #define P849_RBR_NORMAL (P849_RBR_RX_NORMAL | P849_RBR_TX_NORMAL) 384 | #define P849_RBR_SWAP (P849_RBR_RX_OPPOSITE | P849_RBR_TX_OPPOSITE) 385 | #define P849_RBR_EXT (P849_RBR_RX_DISABLED | P849_RBR_TX_OPPOSITE_RX) 386 | 387 | // PHY_PG0_PHYCR2 Def's 388 | #define P849_FAST_ADAPT 0x0001 389 | #define P849_SOFT_RESET 0x0200 390 | #define PHYCR2_SYNC_ENET_EN 0x2000 391 | #define PHYCR2_CLK_OUT_RX_EN 0x1000 392 | #define PHYCR2_BC_WRITE_EN 0x0800 393 | #define PHYCR2_PHY_CMP_MD 0x0400 394 | #define PHYCR2_SOFT_RESET 0x0200 395 | #define PHYCR2_CLK_OUT_DIS 0x0002 396 | 397 | // PHY_PG1_PMDCNFG Def's 398 | #define P849_TEST_MODE_MASK 0x0003 399 | #define P849_TEST_MODE_NORMAL 0x0000 400 | #define P849_TEST_MODE_ED_OB 0x0001 401 | #define P849_TEST_MODE_MDIX_OB 0x0002 402 | #define P849_TEST_MODE_FXC_OB 0x0003 403 | #define P849_LEN100_AEQ 0x0100 404 | #define P849_PMD_SOFT_RESET 0x0200 405 | #define P849_AUTO_NEG_LOOPBACK 0x8000 406 | 407 | // PHY_PG1_TMR1 Def's 408 | #define P849_TEST_SEL_MASK 0x0007 409 | #define P849_TEST_SEL_NORMAL 0x0000 410 | #define P849_TEST_SEL_ADC 0x0001 411 | #define P849_TEST_SEL_CD_OB 0x0002 412 | #define P849_TEST_SEL_AN_RX_SM 0x0004 413 | #define P849_TEST_SEL_AN_TX_SM 0x0005 414 | #define P849_TEST_SEL_AN_ARM_SM 0x0006 415 | #define P849_TEST_SEL_NLPLIT_SM 0x0007 416 | #define P849_NRZ_OBSERVE 0x0008 417 | #define P849_BYP_PLLS 0x0010 418 | #define P849_BYP_ADC 0x0020 419 | #define P849_DIS_IO_TURBO 0x0040 420 | #define P849_ATP0_EN 0x0080 421 | #define P849_ATP1_EN 0x0100 422 | #define P849_SD_OBSERVE 0x0200 423 | #define P849_PWRUP_OBSERVE 0x0400 424 | #define P849_FCO_CTL_EN_OB 0x0800 425 | #define P849_INVERT_ADC_CLK 0x1000 426 | #define P849_MDIX_TX_INV 0x2000 427 | #define P849_ADC_CLK_BYPASS 0x4000 428 | #define P849_ADC_CLK_OE 0x8000 429 | 430 | // PHY_PG1_TMR2 Def's 431 | #define P849_PGM_VFILTER_LOW 0x0001 432 | #define P849_PGM_VFILTER_HIGH 0x0002 433 | #define P849_CGM_VFILTER_LOW 0x0004 434 | #define P849_CGM_VFILTER_HIGH 0x0008 435 | #define P849_MR_AAGC_10MB_MASK 0x00F0 436 | #define P849_MR_AAGC_10MB_SHIFT 4 437 | #define P849_MR_TM_RXSEL_MASK 0x0C00 438 | #define P849_MR_TM_RXSEL_SHIFT 8 439 | #define P849_MR_TM_TXSEL_MASK 0xF000 440 | #define P849_MR_TM_TXSEL_SHIFT 12 441 | 442 | // PHY_PG1_DSP_CTRL1 Def's 443 | #define P849_AGC_ALPHA_MASK 0x0003 444 | #define P849_FREEZE_AGC 0x0004 445 | #define P849_LOAD_AGC 0x0008 446 | #define P849_FREEZE_BLW 0x0010 447 | #define P849_LOAD_BLW 0x0020 448 | #define P849_FORCE_MSE_NOTOK 0x0040 449 | #define P849_FORCE_MSE_OK 0x0080 450 | #define P849_INIT_MSE 0x0100 451 | #define P849_MSE_THSEL 0x0200 452 | #define P849_AGC_7BITS 0x0400 453 | #define P849_BLW_8BITS 0x0800 454 | #define P849_IGNORE_MSEOK 0x2000 455 | #define P849_DIS_PMD_INIT 0x4000 456 | #define P849_PMD_INIT_TEST 0x8000 457 | 458 | // PHY_PG1_DSP_CTRL2 Def's 459 | #define P849_AAGC_THRESH_MASK 0x001F 460 | #define P849_AAGC_FREEZE 0x0020 461 | #define P849_LOAD_AAGC_ACC 0x0040 462 | #define P849_LOAD_AAGC_TMR 0x0080 463 | #define P849_FORCE_AEQ 0x0100 464 | #define P849_FORCE_AEQ_VAL_MASK 0x0600 465 | #define P849_FORCE_AEQ_VAL_SHIFT 9 466 | #define P849_MAX_AEQ_MASK 0x1800 467 | #define P849_MAX_AEQ_SHIFT 11 468 | #define P849_DIS_AEQ_DECR 0x2000 469 | #define P849_LOAD_AEQ_THRESH 0x4000 470 | 471 | // PHY_PG1_TRL_CTRL Def's 472 | #define P849_TRL_ALPHA_MASK 0x0003 473 | #define P849_TRL_ALPHA_SHIFT 0 474 | #define P849_TRL_BETA_MASK 0x000C 475 | #define P849_TRL_BETA_SHIFT 2 476 | #define P849_TRL_THRESH_MASK 0x00F0 477 | #define P849_TRL_THRESH_SHIFT 4 478 | #define P849_TRL_KILLREG 0x0100 479 | #define P849_TRL_SEL_REG 0x0200 480 | #define P849_RST_TRL_ON_ERR 0x0400 481 | #define P849_TRL_FRZ_ACC 0x0800 482 | #define P849_TRL_FRZ_LFO 0x1000 483 | #define P849_LOAD_TRL_PHASE 0x2000 484 | #define P849_LOAD_TRL_LFO 0x4000 485 | #define P849_LOAD_TRL_BETA 0x8000 486 | 487 | // PHY_PG1_DEQ_CTRL Def's 488 | #define P849_KILL_COEFF_N1 0x0001 489 | #define P849_KILL_EQ_TAP0 0x0002 490 | #define P849_KILL_COEF1 0x0004 491 | #define P849_KILL_COEF2 0x0008 492 | #define P849_KILL_COEF3 0x0010 493 | #define P849_FREEZE_COEF 0x0020 494 | #define P849_NOSHIFT_N1 0x0040 495 | #define P849_EQ_LOAD_COEF1 0x0080 496 | #define P849_EQ_LOAD_COEF2 0x0100 497 | #define P849_EQ_LOAD_COEF3 0x0200 498 | #define P849_COEF1_9BITS 0x0400 499 | #define P849_COEF2_8BITS 0x0800 500 | #define P849_COEF3_7BITS 0x1000 501 | #define P849_ALLOW_POS_C1 0x2000 502 | 503 | // PHY_PG1_ANEG_TST Def's 504 | #define P849_LOAD_ARB_TIMER 0x0100 505 | #define P849_LOAD_TX_TIMER 0x0200 506 | #define P849_LOAD_FLP_DATA_TIMER 0x0400 507 | #define P849_LOAD_NLP_MIN_TIMER 0x0800 508 | #define P849_LOAD_NLP_MAX_TIMER 0x1000 509 | #define P849_LOAD_NLP_RX_TIMER 0x2000 510 | #define P849_LOAD_ED_TIMER 0x4000 511 | 512 | // PHY_PG1_EXTCFG Def's 513 | #define P849_ADC_WATCHDOG_EN 0x0001 514 | #define P849_ADC_WATCHDOG_TO_EN 0x0002 515 | #define P849_ADC_WATCHDOG_ERR 0x0004 516 | #define P849_MR_10BT_LR_MASK 0x0018 517 | #define P849_MR_10BT_LR_SHIFT 3 518 | #define P849_MR_NLP_RX_FIX 0x0020 519 | #define P849_ADC_WD_THRESH_MASK 0x07C0 520 | #define P849_ADC_WD_THRESH_SHIFT 6 521 | #define P849_LP_THRESHOLD_MASK 0xF800 522 | #define P849_LP_THRESHOLD_SHIFT 11 523 | 524 | // PHY_PG1_TST_CTRL Def's 525 | #define P849_SAMPLE_DATA 0x0001 526 | #define P849_PLLBIST_RSTN 0x0002 527 | #define P849_PLLBIST_EN 0x0004 528 | #define P849_PLLBIST_MODE 0x0008 529 | #define P849_PLLBIST_DONE 0x0010 530 | #define P849_TEST_DATA_SEL_MASK 0xF800 531 | #define P849_TEST_DATA_SEL_SHIFT 11 532 | 533 | // PHY_PG1_SD_CNFG Def's 534 | #define P849_SDOFFT_MASK 0x000F 535 | #define P849_SDOFFT_SHIFT 0 536 | #define P849_SDONT_MASK 0x00F0 537 | #define P849_SDONT_SHIFT 4 538 | #define P849_SIG_DET_TIME 0x0100 539 | #define P849_FORCE_SIG_DET_PMD 0x0200 540 | #define P849_10B_SCALE_LSB 0x0400 541 | #define P849_MR_SHORT_CABLE 0x0800 542 | #define P849_SIG_DET_TH_DELTA 0x1000 543 | #define P849_100B_PMA_TEST_EN 0x2000 544 | #define P849_AUTO_NEG_TEST_EN 0x4000 545 | #define P849_SIG_DET_PTOP 0x8000 546 | 547 | // PHY_PG2_LEN100_DET Def's 548 | #define P849_CABLE_LEN_MASK 0x00FF 549 | #define P849_CABLE_LEN_SHIFT 0 550 | #define P849_AEQ_VAL_MASK 0x0300 551 | #define P849_AEQ_VAL_SHIFT 8 552 | 553 | // PHY_PG2_FREQ100 Def's 554 | #define P849_FREQ_OFFSET_MASK 0x00FF 555 | #define P849_FREQ_OFFSET_SHIFT 0 556 | #define P849_SEL_FC 0x0100 557 | #define P849_SAMPLE_FREQ 0x8000 558 | 559 | // PHY_PG2_TDR_CTRL Def's 560 | #define P849_RX_THRESHOLD_MASK 0x003F 561 | #define P849_RX_THRESHOLD_SHIFT 0 562 | #define P849_TDR_MIN_MODE 0x0080 563 | #define P849_TDR_WIDTH_MASK 0x0700 564 | #define P849_TDR_WIDTH_SHIFT 8 565 | #define P849_SEND_TDR 0x0800 566 | #define P849_RX_CHANNEL 0x1000 567 | #define P849_TX_CHANNEL 0x2000 568 | #define P849_TDR_100MB 0x4000 569 | #define P849_TDR_ENABLE 0x8000 570 | 571 | // PHY_PG2_TDR_WIN Def's 572 | #define P849_TDR_STOP_MASK 0x00FF 573 | #define P849_TDR_STOP_SHIFT 0 574 | #define P849_TDR_START_MASK 0xFF00 575 | #define P849_TDR_START_SHIFT 8 576 | 577 | // PHY_PG2_TDR_PEAK Def's 578 | #define P849_TDR_PEAK_TIME_MASK 0x00FF 579 | #define P849_TDR_PEAK_TIME_SHIFT 0 580 | #define P849_TDR_PEAK_MASK 0x3F00 581 | #define P849_TDR_PEAK_SHIFT 8 582 | 583 | // PHY_PG2_TDR_THR Def's 584 | #define P849_TDR_THR_TIME_MASK 0x00FF 585 | #define P849_TDR_THR_TIME_SHIFT 0 586 | #define P849_TDR_THR_MET 0x0100 587 | 588 | // PHY_PG2_VAR_CTRL Def's 589 | #define P849_VAR_ENABLE 0x0001 590 | #define P849_VAR_TIMER_MASK 0x0006 591 | #define P849_VAR_FREEZE 0x0008 592 | #define P849_VAR_RDY 0x8000 593 | 594 | // PHY_PG2_LQMR Def's 595 | #define P849_C1_LO_WARN 0x0001 596 | #define P849_C1_HI_WARN 0x0002 597 | #define P849_DAGC_LO_WARN 0x0004 598 | #define P849_DAGC_HI_WARN 0x0008 599 | #define P849_DBLW_LO_WARN 0x0010 600 | #define P849_DBLW_HI_WARN 0x0020 601 | #define P849_FREQ_LO_WARN 0x0040 602 | #define P849_FREQ_HI_WARN 0x0080 603 | #define P849_FC_LO_WARN 0x0100 604 | #define P849_FC_HI_WARN 0x0200 605 | #define P849_BRK_LNK_C1 0x0400 606 | #define P849_BRK_LNK_DAGC 0x0800 607 | #define P849_BRK_LNK_DBLW 0x1000 608 | #define P849_BRK_LNK_FREQ 0x2000 609 | #define P849_BRK_LNK_FC 0x4000 610 | #define P849_LQM_ENABLE 0x8000 611 | 612 | // PHY_PG2_LQDR Def's 613 | #define P849_LQ_THR_DATA_MASK 0x00FF 614 | #define P849_LQ_THR_DATA_SHIFT 0 615 | #define P849_LQ_THR_SEL 0x0100 616 | #define P849_LQ_PARAM_SEL_MASK 0x0E00 617 | #define P849_LQ_PARAM_SEL_SHIFT 9 618 | #define P849_WRITE_LQ_THR 0x1000 619 | #define P849_SAMPLE_PARAM 0x2000 620 | 621 | 622 | //**************************************************************************** 623 | // DP83640 Specific Register Bit Definitions 624 | //**************************************************************************** 625 | 626 | // PHY_PG0_PCFCR Def's 627 | #define P640_PCFCR 0x001F 628 | #define P640_PCF_EN 0x0001 629 | #define P640_PCF_BUF_SHIFT 1 630 | #define P640_PCF_BUF_MASK 0x001E 631 | #define P640_PCF_BC_DIS 0x0020 632 | #define P640_PCF_INT_CTL_SHIFT 6 633 | #define P640_PCF_INT_CTL_MASK 0x00C0 634 | #define P640_PCF_DA_SEL 0x0100 635 | #define P640_PCF_STS_OK 0x4000 636 | #define P640_PCF_STS_ERR 0x8000 637 | 638 | // PHY_PG2_LQMR2 Def's 639 | #define P640_RESTART_ON_VAR 0x0400 640 | #define P640_VAR_HIGH_WARN 0x0002 641 | 642 | // PHY_PG3_CGCR Def's 643 | #define P640_DIS_TRIG_UPD_GATE 0x8000 644 | #define P640_DIS_TX_TS_GATE 0x4000 645 | #define P640_DIS_RX_TS_GATE 0x2000 646 | #define P640_DIS_RX_INFO_GATE 0x1000 647 | #define P640_DIS_EVNT_GATE 0x0800 648 | #define P640_DIS_CLK_UPD_GATE 0x0400 649 | #define P640_DIS_REG125_GATE 0x0200 650 | #define P640_DIS_CLKTX_GATE 0x0100 651 | #define P640_DIS_CLKRX_GATE 0x0080 652 | #define P640_DIS_CLK125_GATE 0x0040 653 | #define P640_DIS_CLKDIV_GATE 0x0020 654 | #define P640_DIS_ADC125_GATE 0x0004 655 | #define P640_DIS_ADC80_GATE 0x0002 656 | #define P640_DIS_REGCLK_GATE 0x0001 657 | 658 | // PHY_PG4_PTP_CTL Def's 659 | #define P640_TRIG_SEL_SHIFT 10 660 | #define P640_TRIG_SEL_MASK 0x1C00 661 | #define P640_TRIG_DIS 0x0200 662 | #define P640_TRIG_EN 0x0100 663 | #define P640_TRIG_READ 0x0080 664 | #define P640_TRIG_LOAD 0x0040 665 | #define P640_PTP_RD_CLK 0x0020 666 | #define P640_PTP_LOAD_CLK 0x0010 667 | #define P640_PTP_STEP_CLK 0x0008 668 | #define P640_PTP_ENABLE 0x0004 669 | #define P640_PTP_DISABLE 0x0002 670 | #define P640_PTP_RESET 0x0001 671 | 672 | // PHY_PG4_PTP_STS Def's 673 | #define P640_TXTS_RDY 0x0800 674 | #define P640_RXTS_RDY 0x0400 675 | #define P640_TRIG_DONE 0x0200 676 | #define P640_EVENT_RDY 0x0100 677 | #define P640_TXTS_IE 0x0008 678 | #define P640_RXTS_IE 0x0004 679 | #define P640_TRIG_IE 0x0002 680 | #define P640_EVENT_IE 0x0001 681 | 682 | // PHY_PG4_PTP_TSTS Def's 683 | #define P640_TRIG7_ERROR 0x8000 684 | #define P640_TRIG7_ACTIVE 0x4000 685 | #define P640_TRIG6_ERROR 0x2000 686 | #define P640_TRIG6_ACTIVE 0x1000 687 | #define P640_TRIG5_ERROR 0x0800 688 | #define P640_TRIG5_ACTIVE 0x0400 689 | #define P640_TRIG4_ERROR 0x0200 690 | #define P640_TRIG4_ACTIVE 0x0100 691 | #define P640_TRIG3_ERROR 0x0080 692 | #define P640_TRIG3_ACTIVE 0x0040 693 | #define P640_TRIG2_ERROR 0x0020 694 | #define P640_TRIG2_ACTIVE 0x0010 695 | #define P640_TRIG1_ERROR 0x0008 696 | #define P640_TRIG1_ACTIVE 0x0004 697 | #define P640_TRIG0_ERROR 0x0002 698 | #define P640_TRIG0_ACTIVE 0x0001 699 | 700 | // PHY_PG4_PTP_RATEH Def's 701 | #define P640_PTP_RATE_DIR 0x8000 702 | #define P640_PTP_TMP_RATE 0x4000 703 | #define P640_PTP_RATE_HI_MASK 0x03FF 704 | #define P640_PTP_RATE_HI_SHIFT 16 705 | 706 | // PHY_PG4_PTP_ESTS Def's 707 | #define P640_EVNTS_MISSED_SHIFT 8 708 | #define P640_EVNTS_MISSED_MASK 0x0700 709 | #define P640_EVNTS_TS_LEN_SHIFT 6 710 | #define P640_EVNTS_TS_LEN_MASK 0x00C0 711 | #define P640_EVNT_RF 0x0020 712 | #define P640_EVNT_NUM_SHIFT 2 713 | #define P640_EVNT_NUM_MASK 0x001C 714 | #define P640_MULT_EVENT 0x0002 715 | #define P640_EVENT_DET 0x0001 716 | 717 | // PHY_PG4_PTP_EDATA Def's 718 | #define P640_E7_RISE 0x8000 719 | #define P640_E7_DET 0x4000 720 | #define P640_E6_RISE 0x2000 721 | #define P640_E6_DET 0x1000 722 | #define P640_E5_RISE 0x0800 723 | #define P640_E5_DET 0x0400 724 | #define P640_E4_RISE 0x0200 725 | #define P640_E4_DET 0x0100 726 | #define P640_E3_RISE 0x0080 727 | #define P640_E3_DET 0x0040 728 | #define P640_E2_RISE 0x0020 729 | #define P640_E2_DET 0x0010 730 | #define P640_E1_RISE 0x0008 731 | #define P640_E1_DET 0x0004 732 | #define P640_E0_RISE 0x0002 733 | #define P640_E0_DET 0x0001 734 | 735 | // PHY_PG5_PTP_TRIG Def's 736 | #define P640_TRIG_PULSE 0x8000 737 | #define P640_TRIG_PER 0x4000 738 | #define P640_TRIG_IF_LATE 0x2000 739 | #define P640_TRIG_NOTIFY 0x1000 740 | #define P640_TRIG_GPIO_SHIFT 8 741 | #define P640_TRIG_GPIO_MASK 0x0F00 742 | #define P640_TRIG_TOGGLE 0x0080 743 | #define P640_TRIG_CSEL_SHIFT 1 744 | #define P640_TRIG_CSEL_MASK 0x000E 745 | #define P640_TRIG_WR 0x0001 746 | 747 | // PHY_PG5_PTP_EVNT Def's 748 | #define P640_EVNT_RISE 0x4000 749 | #define P640_EVNT_FALL 0x2000 750 | #define P640_EVNT_SINGLE 0x1000 751 | #define P640_EVNT_GPIO_SHIFT 8 752 | #define P640_EVNT_GPIO_MASK 0x0F00 753 | #define P640_EVNT_SEL_SHIFT 1 754 | #define P640_EVNT_SEL_MASK 0x000E 755 | #define P640_EVNT_WR 0x0001 756 | 757 | // PHY_PG5_PTP_TXCFG0 Def's 758 | #define P640_SYNC_1STEP 0x8000 759 | #define P640_DR_INSERT 0x2000 760 | #define P640_NTP_TS_EN 0x1000 761 | #define P640_IGNORE_2STEP 0x0800 762 | #define P640_CRC_1STEP 0x0400 763 | #define P640_CHK_1STEP 0x0200 764 | #define P640_IP1588_EN 0x0100 765 | #define P640_TX_L2_EN 0x0080 766 | #define P640_TX_IPV6_EN 0x0040 767 | #define P640_TX_IPV4_EN 0x0020 768 | #define P640_TX_PTP_VER_SHIFT 1 769 | #define P640_TX_PTP_VER_MASK 0x001E 770 | #define P640_TX_TS_EN 0x0001 771 | 772 | // PHY_PG5_PTP_TXCFG1 Def's 773 | #define P640_BYTE0_MASK_SHIFT 8 774 | #define P640_BYTE0_MASK_MASK 0xFF00 775 | #define P640_BYTE0_DATA_SHIFT 0 776 | #define P640_BYTE0_DATA_MASK 0x00FF 777 | 778 | // PHY_PG5_PSF_CFG0 Def's 779 | #define P640_MAC_SRC_ADD_SHIFT 11 780 | #define P640_MAC_SRC_ADD_MASK 0x1800 781 | #define P640_MIN_PRE_SHIFT 8 782 | #define P640_MIN_PRE_MASK 0x0700 783 | #define P640_PKT_ENDIAN 0x0080 784 | #define P640_PKT_IPV4 0x0040 785 | #define P640_PKT_PCFR_EN 0x0020 786 | #define P640_PKT_ERR_EN 0x0010 787 | #define P640_PKT_TXTS_EN 0x0008 788 | #define P640_PKT_RXTS_EN 0x0004 789 | #define P640_PKT_TRIG_EN 0x0002 790 | #define P640_PKT_EVNT_EN 0x0001 791 | 792 | // PHY_PG5_PTP_RXCFG0 Def's 793 | #define P640_DOMAIN_EN 0x8000 794 | #define P640_ALT_MAST_DIS 0x4000 795 | #define P640_USER_IP_SEL 0x2000 796 | #define P640_USER_IP_EN 0x1000 797 | #define P640_RX_SLAVE 0x0800 798 | #define P640_IP1588_EN2 0x0400 799 | #define P640_IP1588_EN1 0x0200 800 | #define P640_IP1588_EN0 0x0100 801 | #define P640_RX_L2_EN 0x0080 802 | #define P640_RX_IPV6_EN 0x0040 803 | #define P640_RX_IPV4_EN 0x0020 804 | #define P640_RX_PTP_VER_SHIFT 1 805 | #define P640_RX_PTP_VER_MASK 0x001E 806 | #define P640_RX_TS_EN 0x0001 807 | 808 | // PHY_PG5_PTP_RXCFG1 Def's 809 | #define P640_BYTE0_MASK_SHIFT 8 810 | #define P640_BYTE0_MASK_MASK 0xFF00 811 | #define P640_BYTE0_DATA_SHIFT 0 812 | #define P640_BYTE0_DATA_MASK 0x00FF 813 | 814 | // PHY_PG5_PTP_RXCFG3 Def's 815 | #define P640_TS_MIN_IFG_SHIFT 12 816 | #define P640_TS_MIN_IFG_MASK 0xF000 817 | #define P640_ACC_UDP 0x0800 818 | #define P640_ACC_CRC 0x0400 819 | #define P640_TS_APPEND 0x0200 820 | #define P640_TS_INSERT 0x0100 821 | #define P640_PTP_DOMAIN_SHIFT 0 822 | #define P640_PTP_DOMAIN_MASK 0x00FF 823 | 824 | // PHY_PG5_PTP_RXCFG4 Def's 825 | #define P640_IPV4_UDP_MOD 0x8000 826 | #define P640_TS_SEC_EN 0x4000 827 | #define P640_TS_SEC_LEN_SHIFT 12 828 | #define P640_TS_SEC_LEN_MASK 0x3000 829 | #define P640_RXTS_NS_OFF_SHIFT 6 830 | #define P640_RXTS_NS_OFF_MASK 0x0FC0 831 | #define P640_RXTS_SEC_OFF_SHIFT 0 832 | #define P640_RXTS_SEC_OFF_MASK 0x003F 833 | 834 | // PHY_PG5_PTP_TRDH Def's 835 | #define P640_PTP_TR_DURH_SHIFT 0 836 | #define P640_PTP_TR_DURH_MASK 0x03FF 837 | 838 | // PHY_PG6_PTP_COC Def's 839 | #define P640_PTP_CLKOUT_EN 0x8000 840 | #define P640_PTP_CLKOUT_SEL 0x4000 841 | #define P640_PTP_CLKOUT_SPSEL 0x2000 842 | #define P640_PTP_CLKDIV_SHIFT 0 843 | #define P640_PTP_CLKDIV_MASK 0x00FF 844 | 845 | // PHY_PG6_PSF_CFG1 Def's 846 | #define P640_PTP_RESERVED_SHIFT 12 847 | #define P640_PTP_RESERVED_MASK 0xF000 848 | #define P640_VERSION_PTP_SHIFT 8 849 | #define P640_VERSION_PTP_MASK 0x0F00 850 | #define P640_TRANSP_SPEC_SHIFT 4 851 | #define P640_TRANSP_SPEC_MASK 0x00F0 852 | #define P640_MESSAGE_TYPE_SHIFT 0 853 | #define P640_MESSAGE_TYPE_MASK 0x000F 854 | 855 | // PHY_PG6_PSF_CFG2 Def's 856 | #define P640_IP_SA_BYTE1_SHIFT 8 857 | #define P640_IP_SA_BYTE1_MASK 0xFF00 858 | #define P640_IP_SA_BYTE0_SHIFT 0 859 | #define P640_IP_SA_BYTE0_MASK 0x00FF 860 | 861 | // PHY_PG6_PSF_CFG3 Def's 862 | #define P640_IP_SA_BYTE3_SHIFT 8 863 | #define P640_IP_SA_BYTE3_MASK 0xFF00 864 | #define P640_IP_SA_BYTE2_SHIFT 0 865 | #define P640_IP_SA_BYTE2_MASK 0x00FF 866 | 867 | // PHY_PG6_PTP_SFDCFG Def's 868 | #define P640_TX_SFD_GPIO_SHIFT 4 869 | #define P640_TX_SFD_GPIO_MASK 0x00F0 870 | #define P640_RX_SFD_GPIO_SHIFT 0 871 | #define P640_RX_SFD_GPIO_MASK 0x000F 872 | 873 | // PHY_PG6_PTP_INTCTL Def's 874 | #define P640_PTP_INT_GPIO_SHIFT 0 875 | #define P640_PTP_INT_GPIO_MASK 0x000F 876 | 877 | // PHY_PG6_PTP_CLKSRC Def's 878 | #define P640_CLK_SRC_SHIFT 14 879 | #define P640_CLK_SRC_MASK 0xC000 880 | #define P640_CLK_SRC_PER_SHIFT 0 881 | #define P640_CLK_SRC_PER_MASK 0x007F 882 | 883 | // PHY_PG6_PTP_OFF Def's 884 | #define P640_PTP_OFFSET_SHIFT 0 885 | #define P640_PTP_OFFSET_MASK 0x00FF 886 | 887 | // PHY_PG6_PTP_GPIOMON Def's 888 | #define P640_PTP_GPIO_IN_SHIFT 0 889 | #define P640_PTP_GPIO_IN_MASK 0x0FFF 890 | 891 | // PHY_PG6_PTP_RXHASH Def's 892 | #define P640_RX_HASH_EN 0x1000 893 | #define P640_PTP_RX_HASH_SHIFT 0 894 | #define P640_PTP_RX_HASH_MASK 0x0FFF 895 | 896 | #endif // _EPL_REGS_INCLUDE -------------------------------------------------------------------------------- /MainDemo.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * 3 | * Main Application Entry Point and TCP/IP Stack Demo 4 | * Module for Microchip TCP/IP Stack 5 | * -Demonstrates how to call and use the Microchip TCP/IP stack 6 | * -Reference: Microchip TCP/IP Stack Help (TCPIP Stack Help.chm) 7 | * 8 | ********************************************************************* 9 | * FileName: MainDemo.c 10 | * Dependencies: TCPIP.h 11 | * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32 12 | * Compiler: Microchip C32 v1.11b or higher 13 | * Microchip C30 v3.24 or higher 14 | * Microchip C18 v3.36 or higher 15 | * Company: Microchip Technology, Inc. 16 | * 17 | * Software License Agreement 18 | * 19 | * Copyright (C) 2002-2010 Microchip Technology Inc. All rights 20 | * reserved. 21 | * 22 | * File Description: 23 | * Change History: 24 | * Rev Description 25 | * ---- ----------------------------------------- 26 | * 1.0 Initial release 27 | * V5.36 ---- STACK_USE_MPFS support has been removed 28 | ********************************************************************/ 29 | /* 30 | * This macro uniquely defines this file as the main entry point. 31 | * There should only be one such definition in the entire project, 32 | * and this file must define the AppConfig variable as described below. 33 | */ 34 | #define THIS_IS_STACK_APPLICATION 35 | 36 | // Include all headers for any enabled TCPIP Stack functions 37 | #include "TCPIP Stack/TCPIP.h" 38 | 39 | #if defined(STACK_USE_ZEROCONF_LINK_LOCAL) 40 | #include "TCPIP Stack/ZeroconfLinkLocal.h" 41 | #endif 42 | #if defined(STACK_USE_ZEROCONF_MDNS_SD) 43 | #include "TCPIP Stack/ZeroconfMulticastDNS.h" 44 | #endif 45 | 46 | #include "dp83640cfg1588.h" 47 | #include "dp83640ptp1588.h" // IEEE 1588 PTPSend() 48 | #include "ClientServer.h" 49 | 50 | // Include functions specific to this stack application 51 | #include "MainDemo.h" 52 | 53 | // Used for Wi-Fi assertions 54 | #define WF_MODULE_NUMBER WF_MODULE_MAIN_DEMO 55 | 56 | // Declare AppConfig structure and some other supporting stack variables 57 | APP_CONFIG AppConfig; 58 | static unsigned short wOriginalAppConfigChecksum; // Checksum of the ROM defaults for AppConfig 59 | BYTE AN0String[8]; 60 | 61 | // Use UART2 instead of UART1 for stdout (printf functions). Explorer 16 62 | // serial port hardware is on PIC UART2 module. 63 | #if defined(EXPLORER_16) || defined(PIC24FJ256DA210_DEV_BOARD) 64 | int __C30_UART = 2; 65 | #endif 66 | 67 | 68 | // Private helper functions. 69 | // These may or may not be present in all applications. 70 | static void InitAppConfig(void); 71 | static void InitializeBoard(void); 72 | static void ProcessIO(void); 73 | #if defined(WF_CS_TRIS) 74 | static void WF_Connect(void); 75 | extern BOOL gRFModuleVer1209orLater; 76 | #endif 77 | 78 | // 79 | // PIC18 Interrupt Service Routines 80 | // 81 | // NOTE: Several PICs, including the PIC18F4620 revision A3 have a RETFIE FAST/MOVFF bug 82 | // The interruptlow keyword is used to work around the bug when using C18 83 | #if defined(__18CXX) 84 | #if defined(HI_TECH_C) 85 | void interrupt low_priority LowISR(void) 86 | #else 87 | #pragma interruptlow LowISR 88 | void LowISR(void) 89 | #endif 90 | { 91 | TickUpdate(); 92 | } 93 | 94 | #if defined(HI_TECH_C) 95 | void interrupt HighISR(void) 96 | #else 97 | #pragma interruptlow HighISR 98 | void HighISR(void) 99 | #endif 100 | { 101 | #if defined(STACK_USE_UART2TCP_BRIDGE) 102 | UART2TCPBridgeISR(); 103 | #endif 104 | 105 | #if defined(WF_CS_TRIS) 106 | WFEintISR(); 107 | #endif // WF_CS_TRIS 108 | } 109 | 110 | #if !defined(HI_TECH_C) 111 | #pragma code lowVector=0x18 112 | void LowVector(void){_asm goto LowISR _endasm} 113 | #pragma code highVector=0x8 114 | void HighVector(void){_asm goto HighISR _endasm} 115 | #pragma code // Return to default code section 116 | #endif 117 | 118 | // C30 and C32 Exception Handlers 119 | // If your code gets here, you either tried to read or write 120 | // a NULL pointer, or your application overflowed the stack 121 | // by having too many local variables or parameters declared. 122 | #elif defined(__C30__) 123 | void _ISR __attribute__((__no_auto_psv__)) _AddressError(void) 124 | { 125 | Nop(); 126 | Nop(); 127 | } 128 | void _ISR __attribute__((__no_auto_psv__)) _StackError(void) 129 | { 130 | Nop(); 131 | Nop(); 132 | } 133 | 134 | #elif defined(__C32__) 135 | void _general_exception_handler(unsigned cause, unsigned status) 136 | { 137 | Nop(); 138 | Nop(); 139 | } 140 | #endif 141 | 142 | 143 | // 144 | // Main application entry point. 145 | // 146 | #if defined(__18CXX) 147 | void main(void) 148 | #else 149 | int main(void) 150 | #endif 151 | { 152 | static DWORD t = 0; 153 | static DWORD dwLastIP = 0; 154 | 155 | // Initialize application specific hardware 156 | InitializeBoard(); 157 | 158 | #if defined(USE_LCD) 159 | // Initialize and display the stack version on the LCD 160 | LCDInit(); 161 | DelayMs(100); 162 | strcpypgm2ram((char*)LCDText, "TCPStack " TCPIP_STACK_VERSION " " 163 | " "); 164 | LCDUpdate(); 165 | #endif 166 | 167 | // Initialize stack-related hardware components that may be 168 | // required by the UART configuration routines 169 | TickInit(); 170 | #if defined(STACK_USE_MPFS2) 171 | MPFSInit(); 172 | #endif 173 | 174 | // Initialize Stack and application related NV variables into AppConfig. 175 | InitAppConfig(); 176 | 177 | // Initiates board setup process if button is depressed 178 | // on startup 179 | if(BUTTON0_IO == 0u) 180 | { 181 | #if defined(EEPROM_CS_TRIS) || defined(SPIFLASH_CS_TRIS) 182 | // Invalidate the EEPROM contents if BUTTON0 is held down for more than 4 seconds 183 | DWORD StartTime = TickGet(); 184 | LED_PUT(0x00); 185 | 186 | while(BUTTON0_IO == 0u) 187 | { 188 | if(TickGet() - StartTime > 4*TICK_SECOND) 189 | { 190 | #if defined(EEPROM_CS_TRIS) 191 | XEEBeginWrite(0x0000); 192 | XEEWrite(0xFF); 193 | XEEWrite(0xFF); 194 | XEEEndWrite(); 195 | #elif defined(SPIFLASH_CS_TRIS) 196 | SPIFlashBeginWrite(0x0000); 197 | SPIFlashWrite(0xFF); 198 | SPIFlashWrite(0xFF); 199 | #endif 200 | 201 | #if defined(STACK_USE_UART) 202 | putrsUART("\r\n\r\nBUTTON0 held for more than 4 seconds. Default settings restored.\r\n\r\n"); 203 | #endif 204 | 205 | LED_PUT(0x0F); 206 | while((LONG)(TickGet() - StartTime) <= (LONG)(9*TICK_SECOND/2)); 207 | LED_PUT(0x00); 208 | while(BUTTON0_IO == 0u); 209 | Reset(); 210 | break; 211 | } 212 | } 213 | #endif 214 | 215 | #if defined(STACK_USE_UART) 216 | DoUARTConfig(); 217 | #endif 218 | } 219 | 220 | // Initialize core stack layers (MAC, ARP, TCP, UDP) and 221 | // application modules (HTTP, SNMP, etc.) 222 | StackInit(); // calls TCPInit() 223 | 224 | #if defined(WF_CS_TRIS) 225 | WF_Connect(); 226 | #endif 227 | 228 | // Initialize any application-specific modules or functions/ 229 | // For this demo application, this only includes the 230 | // UART 2 TCP Bridge 231 | #if defined(STACK_USE_UART2TCP_BRIDGE) 232 | UART2TCPBridgeInit(); 233 | #endif 234 | 235 | #if defined(STACK_USE_ZEROCONF_LINK_LOCAL) 236 | ZeroconfLLInitialize(); 237 | #endif 238 | 239 | #if defined(STACK_USE_ZEROCONF_MDNS_SD) 240 | mDNSInitialize(MY_DEFAULT_HOST_NAME); 241 | mDNSServiceRegister( 242 | (const char *) "DemoWebServer", // base name of the service 243 | "_http._tcp.local", // type of the service 244 | 80, // TCP or UDP port, at which this service is available 245 | ((const BYTE *)"path=/index.htm"), // TXT info 246 | 1, // auto rename the service when if needed 247 | NULL, // no callback function 248 | NULL // no application context 249 | ); 250 | 251 | mDNSMulticastFilterRegister(); 252 | #endif 253 | 254 | //AM Initialize IEEE 1588 related functionality 255 | PTPEnable(TRUE); 256 | PTPClockSet(0,0); 257 | // NS_UINT clockConfigOptions, NS_UINT ptpClockDivideByValue, NS_UINT ptpClockSource, NS_UINT ptpClockSourcePeriod 258 | // ptpClockSource: 0x00 - 125MHz from internal PGM (default), 0x01 - Divide-by-N from 125MHz internal PGM 259 | // PTPSetClockConfig (CLKOPT_CLK_OUT_EN,0xFF,0x00,0); 260 | PTPClockOutEnable(TRUE,250); //250 261 | PTPPulseOutStart(); 262 | 263 | // void PTPSetEventConfig (IN NS_UINT event,IN NS_BOOL eventRiseFlag,IN NS_BOOL eventFallFlag,IN NS_BOOL eventSingle,IN NS_UINT gpioConnection); 264 | // event - The event to configure, 0 – 7. 265 | // eventRiseFlag - If set to TRUE, enables detection of rising edge on Event input. 266 | // eventFallFlag - If set to TRUE, enables detection of falling edge on Event input. 267 | // eventSingle - If set to TRUE, enables single event capture operation. 268 | // gpioConnection - The GPIO pin the event should be connected to. A value of 0 – 12. If 0 is specified no GPIO pin connection is made. 269 | const unsigned int GPIO_PIN = 10; // GPIO 1,2,3,4,8,9,12 have internal PullDOWN resisotors, others have pullUPs (see datasheet page 13) 270 | PTPSetEventConfig(0, FALSE, TRUE, TRUE, GPIO_PIN); 271 | 272 | BOOL master; 273 | master = !(BOOL)(PORTDbits.RD4); // jumper setting 274 | PTPConfigRxTimeInsert(); 275 | PTPEnableSyncTimestampInsertion(master); // insertion of timestamp in sync msgs 276 | if(!master){ 277 | PTPEnableDelayReqTimestampInsertion(TRUE); // allow Delay_Req timestamp insertion 278 | EnableSynchronousEthernet(TRUE); // recover clock on the slave side 279 | } 280 | PTPEthInit(); // configures default for PTPSendSync() and PTPProcess() 281 | 282 | // DEBUGGING !!! 283 | // unsigned int seconds = 0; 284 | // unsigned int nanoSeconds = 0; 285 | // PTPClockRead(&seconds, &nanoSeconds); 286 | // PTPClockStepAdjustment(30,0); 287 | // PTPClockRead(&seconds, &nanoSeconds); 288 | // PTPClockStepAdjustment(-90,0); 289 | // PTPClockRead(&seconds, &nanoSeconds); 290 | // PTPClockStepAdjustment(0,-0x03FFFFFE); 291 | // PTPClockRead(&seconds, &nanoSeconds); 292 | // PTPClockRead(&seconds, &nanoSeconds); // break here 293 | 294 | 295 | // Now that all items are initialized, begin the co-operative 296 | // multitasking loop. This infinite loop will continuously 297 | // execute all stack-related tasks, as well as your own 298 | // application's functions. Custom functions should be added 299 | // at the end of this loop. 300 | // Note that this is a "co-operative mult-tasking" mechanism 301 | // where every task performs its tasks (whether all in one shot 302 | // or part of it) and returns so that other tasks can do their 303 | // job. 304 | // If a task needs very long time to do its job, it must be broken 305 | // down into smaller pieces so that other tasks can have CPU time. 306 | while(1){ 307 | // This task performs normal stack task including checking 308 | // for incoming packet, type of packet and calling 309 | // appropriate stack entity to process it. 310 | StackTask(); 311 | 312 | // Blink LED0 (right most one) every second. 313 | if(TickGet() - t >= TICK_SECOND/2ul){ 314 | // re-enable GPIO inputs and send PTP Sync twice per second on master 315 | PTPSetEventConfig(0, FALSE, TRUE, TRUE, GPIO_PIN); 316 | if(master){ 317 | PTPSendSync(); 318 | } 319 | 320 | t = TickGet(); 321 | LED0_IO ^= 1; 322 | } 323 | 324 | unsigned int sec, ns; 325 | // clear timestamps queue in order for PHY to function correctly 326 | PTPGetTxTimestamp(&sec, &ns); // clear & discard TX timestamps 327 | PTPGetRxTimestamp(&sec, &ns); // clear & discard RX timestamps 328 | 329 | if(PTPCheckForEvents()){ 330 | LED1_IO ^= 1; 331 | unsigned int eventNum, raiseFlag, eventsMissed, seconds, nanoSec; 332 | if( PTPGetEvent(&eventNum, &raiseFlag, &seconds, &nanoSec, &eventsMissed ) ){ 333 | char msg[128]; 334 | sprintf(msg," Timestamp from %s: %us %uns", master?"master":" slave", seconds, nanoSec); 335 | Debug(msg); 336 | sendTimeStampUdp(seconds, nanoSec); 337 | sendTimeStampTcp(seconds, nanoSec); 338 | } 339 | } 340 | 341 | #if defined(WF_CS_TRIS) 342 | if (gRFModuleVer1209orLater) 343 | WiFiTask(); 344 | #endif 345 | 346 | // This tasks invokes each of the core stack application tasks 347 | StackApplications(); 348 | 349 | #if defined(STACK_USE_ZEROCONF_LINK_LOCAL) 350 | ZeroconfLLProcess(); 351 | #endif 352 | 353 | #if defined(STACK_USE_ZEROCONF_MDNS_SD) 354 | mDNSProcess(); 355 | // Use this function to exercise service update function 356 | // HTTPUpdateRecord(); 357 | #endif 358 | 359 | // Process application specific tasks here. 360 | // For this demo app, this will include the Generic TCP 361 | // client and servers, and the SNMP, Ping, and SNMP Trap 362 | // demos. Following that, we will process any IO from 363 | // the inputs on the board itself. 364 | // Any custom modules or processing you need to do should 365 | // go here. 366 | #if defined(STACK_USE_GENERIC_TCP_CLIENT_EXAMPLE) 367 | GenericTCPClient(); 368 | #endif 369 | 370 | #if defined(STACK_USE_GENERIC_TCP_SERVER_EXAMPLE) 371 | GenericTCPServer(); 372 | #endif 373 | 374 | #if defined(STACK_USE_SMTP_CLIENT) 375 | // SMTPDemo(); 376 | #endif 377 | 378 | #if defined(STACK_USE_ICMP_CLIENT) 379 | PingDemo(); 380 | #endif 381 | 382 | #if defined(STACK_USE_SNMP_SERVER) && !defined(SNMP_TRAP_DISABLED) 383 | //User should use one of the following SNMP demo 384 | // This routine demonstrates V1 or V2 trap formats with one variable binding. 385 | SNMPTrapDemo(); 386 | 387 | #if defined(SNMP_STACK_USE_V2_TRAP) || defined(SNMP_V1_V2_TRAP_WITH_SNMPV3) 388 | //This routine provides V2 format notifications with multiple (3) variable bindings 389 | //User should modify this routine to send v2 trap format notifications with the required varbinds. 390 | //SNMPV2TrapDemo(); 391 | #endif 392 | if(gSendTrapFlag) 393 | SNMPSendTrap(); 394 | #endif 395 | 396 | #if defined(STACK_USE_BERKELEY_API) 397 | BerkeleyTCPClientDemo(); 398 | BerkeleyTCPServerDemo(); 399 | BerkeleyUDPClientDemo(); 400 | #endif 401 | 402 | //A ProcessIO(); // ADC from a pot 403 | 404 | // If the local IP address has changed (ex: due to DHCP lease change) 405 | // write the new IP address to the LCD display, UART, and Announce 406 | // service 407 | if(dwLastIP != AppConfig.MyIPAddr.Val){ 408 | dwLastIP = AppConfig.MyIPAddr.Val; 409 | 410 | #if defined(STACK_USE_UART) 411 | putrsUART((ROM char*)"\r\nNew IP Address: "); 412 | #endif 413 | 414 | // display IP on LCD screen 415 | //A DisplayIPValue(AppConfig.MyIPAddr); 416 | 417 | #if defined(STACK_USE_UART) 418 | putrsUART((ROM char*)"\r\n"); 419 | #endif 420 | 421 | #if defined(STACK_USE_ANNOUNCE) 422 | AnnounceIP(); 423 | #endif 424 | 425 | #if defined(STACK_USE_ZEROCONF_MDNS_SD) 426 | mDNSFillHostRecord(); 427 | #endif 428 | } 429 | } // while(1) 430 | } 431 | 432 | #if defined(WF_CS_TRIS) 433 | /***************************************************************************** 434 | * FUNCTION: WF_Connect 435 | * 436 | * RETURNS: None 437 | * 438 | * PARAMS: None 439 | * 440 | * NOTES: Connects to an 802.11 network. Customize this function as needed 441 | * for your application. 442 | *****************************************************************************/ 443 | static void WF_Connect(void) 444 | { 445 | UINT8 ConnectionProfileID; 446 | UINT8 channelList[] = MY_DEFAULT_CHANNEL_LIST; 447 | 448 | /* create a Connection Profile */ 449 | WF_CPCreate(&ConnectionProfileID); 450 | 451 | #if defined(STACK_USE_UART) 452 | putrsUART("Set SSID ("); 453 | putsUART(AppConfig.MySSID); 454 | putrsUART(")\r\n"); 455 | #endif 456 | WF_CPSetSsid(ConnectionProfileID, 457 | AppConfig.MySSID, 458 | AppConfig.SsidLength); 459 | 460 | #if defined(STACK_USE_UART) 461 | putrsUART("Set Network Type\r\n"); 462 | #endif 463 | WF_CPSetNetworkType(ConnectionProfileID, MY_DEFAULT_NETWORK_TYPE); 464 | 465 | #if defined(STACK_USE_UART) 466 | putrsUART("Set Scan Type\r\n"); 467 | #endif 468 | WF_CASetScanType(MY_DEFAULT_SCAN_TYPE); 469 | 470 | #if defined(STACK_USE_UART) 471 | putrsUART("Set Channel List\r\n"); 472 | #endif 473 | WF_CASetChannelList(channelList, sizeof(channelList)); 474 | 475 | #if defined(STACK_USE_UART) 476 | putrsUART("Set list retry count\r\n"); 477 | #endif 478 | // The Retry Count parameter tells the WiFi Connection manager how many attempts to make when trying 479 | // to connect to an existing network. In the Infrastructure case, the default is to retry forever so that 480 | // if the AP is turned off or out of range, the radio will continue to attempt a connection until the 481 | // AP is eventually back on or in range. In the Adhoc case, the default is to retry 3 times since the 482 | // purpose of attempting to establish a network in the Adhoc case is only to verify that one does not 483 | // initially exist. If the retry count was set to WF_RETRY_FOREVER in the AdHoc mode, an AdHoc network 484 | // would never be established. The constants MY_DEFAULT_LIST_RETRY_COUNT_ADHOC and 485 | // MY_DEFAULT_LIST_RETRY_COUNT_INFRASTRUCTURE have been created specifically for the June 2011 MAL release. 486 | #if defined(EZ_CONFIG_STORE) 487 | if (AppConfig.networkType == WF_ADHOC) 488 | WF_CASetListRetryCount(MY_DEFAULT_LIST_RETRY_COUNT_ADHOC); 489 | else 490 | WF_CASetListRetryCount(MY_DEFAULT_LIST_RETRY_COUNT_INFRASTRUCTURE); 491 | #else 492 | #if (MY_DEFAULT_NETWORK_TYPE == WF_ADHOC) 493 | WF_CASetListRetryCount(MY_DEFAULT_LIST_RETRY_COUNT_ADHOC); 494 | #else 495 | WF_CASetListRetryCount(MY_DEFAULT_LIST_RETRY_COUNT_INFRASTRUCTURE); 496 | #endif 497 | #endif 498 | 499 | 500 | #if defined(STACK_USE_UART) 501 | putrsUART("Set Event Notify\r\n"); 502 | #endif 503 | WF_CASetEventNotificationAction(MY_DEFAULT_EVENT_NOTIFICATION_LIST); 504 | 505 | #if defined(STACK_USE_UART) 506 | putrsUART("Set Beacon Timeout\r\n"); 507 | #endif 508 | WF_CASetBeaconTimeout(40); 509 | 510 | if (gRFModuleVer1209orLater) 511 | { 512 | // If WEP security is used, set WEP Key Type. The default WEP Key Type is Shared Key. 513 | if (AppConfig.SecurityMode == WF_SECURITY_WEP_40 || AppConfig.SecurityMode == WF_SECURITY_WEP_104) 514 | { 515 | WF_CPSetWepKeyType(ConnectionProfileID, MY_DEFAULT_WIFI_SECURITY_WEP_KEYTYPE); 516 | } 517 | } 518 | 519 | /* Set Security */ 520 | #if (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_OPEN) 521 | #if defined(STACK_USE_UART) 522 | putrsUART("Set Security (Open)\r\n"); 523 | #endif 524 | #elif (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WEP_40) 525 | #if defined(STACK_USE_UART) 526 | putrsUART("Set Security (WEP40)\r\n"); 527 | #endif 528 | #elif (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WEP_104) 529 | #if defined(STACK_USE_UART) 530 | putrsUART("Set Security (WEP104)\r\n"); 531 | #endif 532 | #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_WITH_KEY 533 | #if defined(STACK_USE_UART) 534 | putrsUART("Set Security (WPA with key)\r\n"); 535 | #endif 536 | #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA2_WITH_KEY 537 | #if defined(STACK_USE_UART) 538 | putrsUART("Set Security (WPA2 with key)\r\n"); 539 | #endif 540 | #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_WITH_PASS_PHRASE 541 | #if defined(STACK_USE_UART) 542 | putrsUART("Set Security (WPA with pass phrase)\r\n"); 543 | #endif 544 | #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA2_WITH_PASS_PHRASE 545 | #if defined(STACK_USE_UART) 546 | putrsUART("Set Security (WPA2 with pass phrase)\r\n"); 547 | #endif 548 | #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_AUTO_WITH_KEY 549 | #if defined(STACK_USE_UART) 550 | putrsUART("Set Security (WPA with key, auto-select)\r\n"); 551 | #endif 552 | #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE 553 | #if defined(STACK_USE_UART) 554 | putrsUART("Set Security (WPA with pass phrase, auto-select)\r\n"); 555 | #endif 556 | #endif /* MY_DEFAULT_WIFI_SECURITY_MODE */ 557 | 558 | WF_CPSetSecurity(ConnectionProfileID, 559 | AppConfig.SecurityMode, 560 | AppConfig.WepKeyIndex, /* only used if WEP enabled */ 561 | AppConfig.SecurityKey, 562 | AppConfig.SecurityKeyLength); 563 | 564 | #if MY_DEFAULT_PS_POLL == WF_ENABLED 565 | WF_PsPollEnable(TRUE); 566 | if (gRFModuleVer1209orLater) 567 | WFEnableDeferredPowerSave(); 568 | #else 569 | WF_PsPollDisable(); 570 | #endif 571 | 572 | 573 | #ifdef WF_AGGRESSIVE_PS 574 | if (gRFModuleVer1209orLater) 575 | WFEnableAggressivePowerSave(); 576 | #endif 577 | 578 | #if defined(STACK_USE_UART) 579 | putrsUART("Start WiFi Connect\r\n"); 580 | #endif 581 | WF_CMConnect(ConnectionProfileID); 582 | } 583 | #endif /* WF_CS_TRIS */ 584 | 585 | // Writes an IP address to the LCD display and the UART as available 586 | void DisplayIPValue(IP_ADDR IPVal) 587 | { 588 | // printf("%u.%u.%u.%u", IPVal.v[0], IPVal.v[1], IPVal.v[2], IPVal.v[3]); 589 | #if defined (__dsPIC33E__) || defined (__PIC24E__) 590 | static BYTE IPDigit[4]; /* Needs to be declared as static to avoid the array getting optimized by C30 v3.30 compiler for dsPIC33E/PIC24E. 591 | Otherwise the LCD displays corrupted IP address on Explorer 16. To be fixed in the future compiler release*/ 592 | #else 593 | BYTE IPDigit[4]; 594 | #endif 595 | BYTE i; 596 | #ifdef USE_LCD 597 | BYTE j; 598 | BYTE LCDPos=16; 599 | #endif 600 | 601 | for(i = 0; i < sizeof(IP_ADDR); i++) 602 | { 603 | uitoa((WORD)IPVal.v[i], IPDigit); 604 | 605 | #if defined(STACK_USE_UART) 606 | putsUART((char *) IPDigit); 607 | #endif 608 | 609 | #ifdef USE_LCD 610 | for(j = 0; j < strlen((char*)IPDigit); j++) 611 | { 612 | LCDText[LCDPos++] = IPDigit[j]; 613 | } 614 | if(i == sizeof(IP_ADDR)-1) 615 | break; 616 | LCDText[LCDPos++] = '.'; 617 | #else 618 | if(i == sizeof(IP_ADDR)-1) 619 | break; 620 | #endif 621 | 622 | #if defined(STACK_USE_UART) 623 | while(BusyUART()); 624 | WriteUART('.'); 625 | #endif 626 | } 627 | 628 | #ifdef USE_LCD 629 | if(LCDPos < 32u) 630 | LCDText[LCDPos] = 0; 631 | LCDUpdate(); 632 | #endif 633 | } 634 | 635 | // Processes A/D data from the potentiometer 636 | static void ProcessIO(void) 637 | { 638 | #if defined(__C30__) || defined(__C32__) 639 | // Convert potentiometer result into ASCII string 640 | uitoa((WORD)ADC1BUF0, AN0String); 641 | #else 642 | // AN0 should already be set up as an analog input 643 | ADCON0bits.GO = 1; 644 | 645 | // Wait until A/D conversion is done 646 | while(ADCON0bits.GO); 647 | 648 | // AD converter errata work around (ex: PIC18F87J10 A2) 649 | #if !defined(__18F87J50) && !defined(_18F87J50) && !defined(__18F87J11) && !defined(_18F87J11) 650 | { 651 | BYTE temp = ADCON2; 652 | ADCON2 |= 0x7; // Select Frc mode by setting ADCS0/ADCS1/ADCS2 653 | ADCON2 = temp; 654 | } 655 | #endif 656 | 657 | // Convert 10-bit value into ASCII string 658 | uitoa(*((WORD*)(&ADRESL)), AN0String); 659 | #endif 660 | } 661 | 662 | 663 | /**************************************************************************** 664 | Function: 665 | static void InitializeBoard(void) 666 | 667 | Description: 668 | This routine initializes the hardware. It is a generic initialization 669 | routine for many of the Microchip development boards, using definitions 670 | in HardwareProfile.h to determine specific initialization. 671 | 672 | Precondition: 673 | None 674 | 675 | Parameters: 676 | None - None 677 | 678 | Returns: 679 | None 680 | 681 | Remarks: 682 | None 683 | ***************************************************************************/ 684 | static void InitializeBoard(void) 685 | { 686 | // LEDs 687 | LED0_TRIS = 0; 688 | LED1_TRIS = 0; 689 | LED2_TRIS = 0; 690 | LED3_TRIS = 0; 691 | LED4_TRIS = 0; 692 | LED5_TRIS = 0; 693 | LED6_TRIS = 0; 694 | LED7_TRIS = 0; 695 | LED_PUT(0x00); 696 | 697 | #if defined(__18CXX) 698 | // Enable 4x/5x/96MHz PLL on PIC18F87J10, PIC18F97J60, PIC18F87J50, etc. 699 | OSCTUNE = 0x40; 700 | 701 | // Set up analog features of PORTA 702 | 703 | // PICDEM.net 2 board has POT on AN2, Temp Sensor on AN3 704 | #if defined(PICDEMNET2) 705 | ADCON0 = 0x09; // ADON, Channel 2 706 | ADCON1 = 0x0B; // Vdd/Vss is +/-REF, AN0, AN1, AN2, AN3 are analog 707 | #elif defined(PICDEMZ) 708 | ADCON0 = 0x81; // ADON, Channel 0, Fosc/32 709 | ADCON1 = 0x0F; // Vdd/Vss is +/-REF, AN0, AN1, AN2, AN3 are all digital 710 | #elif defined(__18F87J11) || defined(_18F87J11) || defined(__18F87J50) || defined(_18F87J50) 711 | ADCON0 = 0x01; // ADON, Channel 0, Vdd/Vss is +/-REF 712 | WDTCONbits.ADSHR = 1; 713 | ANCON0 = 0xFC; // AN0 (POT) and AN1 (temp sensor) are anlog 714 | ANCON1 = 0xFF; 715 | WDTCONbits.ADSHR = 0; 716 | #else 717 | ADCON0 = 0x01; // ADON, Channel 0 718 | ADCON1 = 0x0E; // Vdd/Vss is +/-REF, AN0 is analog 719 | #endif 720 | ADCON2 = 0xBE; // Right justify, 20TAD ACQ time, Fosc/64 (~21.0kHz) 721 | 722 | 723 | // Enable internal PORTB pull-ups 724 | INTCON2bits.RBPU = 0; 725 | 726 | // Configure USART 727 | TXSTA = 0x20; 728 | RCSTA = 0x90; 729 | 730 | // See if we can use the high baud rate setting 731 | #if ((GetPeripheralClock()+2*BAUD_RATE)/BAUD_RATE/4 - 1) <= 255 732 | SPBRG = (GetPeripheralClock()+2*BAUD_RATE)/BAUD_RATE/4 - 1; 733 | TXSTAbits.BRGH = 1; 734 | #else // Use the low baud rate setting 735 | SPBRG = (GetPeripheralClock()+8*BAUD_RATE)/BAUD_RATE/16 - 1; 736 | #endif 737 | 738 | 739 | // Enable Interrupts 740 | RCONbits.IPEN = 1; // Enable interrupt priorities 741 | INTCONbits.GIEH = 1; 742 | INTCONbits.GIEL = 1; 743 | 744 | // Do a calibration A/D conversion 745 | #if defined(__18F87J10) || defined(__18F86J15) || defined(__18F86J10) || defined(__18F85J15) || defined(__18F85J10) || defined(__18F67J10) || defined(__18F66J15) || defined(__18F66J10) || defined(__18F65J15) || defined(__18F65J10) || defined(__18F97J60) || defined(__18F96J65) || defined(__18F96J60) || defined(__18F87J60) || defined(__18F86J65) || defined(__18F86J60) || defined(__18F67J60) || defined(__18F66J65) || defined(__18F66J60) || \ 746 | defined(_18F87J10) || defined(_18F86J15) || defined(_18F86J10) || defined(_18F85J15) || defined(_18F85J10) || defined(_18F67J10) || defined(_18F66J15) || defined(_18F66J10) || defined(_18F65J15) || defined(_18F65J10) || defined(_18F97J60) || defined(_18F96J65) || defined(_18F96J60) || defined(_18F87J60) || defined(_18F86J65) || defined(_18F86J60) || defined(_18F67J60) || defined(_18F66J65) || defined(_18F66J60) 747 | ADCON0bits.ADCAL = 1; 748 | ADCON0bits.GO = 1; 749 | while(ADCON0bits.GO); 750 | ADCON0bits.ADCAL = 0; 751 | #elif defined(__18F87J11) || defined(__18F86J16) || defined(__18F86J11) || defined(__18F67J11) || defined(__18F66J16) || defined(__18F66J11) || \ 752 | defined(_18F87J11) || defined(_18F86J16) || defined(_18F86J11) || defined(_18F67J11) || defined(_18F66J16) || defined(_18F66J11) || \ 753 | defined(__18F87J50) || defined(__18F86J55) || defined(__18F86J50) || defined(__18F67J50) || defined(__18F66J55) || defined(__18F66J50) || \ 754 | defined(_18F87J50) || defined(_18F86J55) || defined(_18F86J50) || defined(_18F67J50) || defined(_18F66J55) || defined(_18F66J50) 755 | ADCON1bits.ADCAL = 1; 756 | ADCON0bits.GO = 1; 757 | while(ADCON0bits.GO); 758 | ADCON1bits.ADCAL = 0; 759 | #endif 760 | 761 | #else // 16-bit C30 and and 32-bit C32 762 | #if defined(__PIC32MX__) 763 | { 764 | // Enable multi-vectored interrupts 765 | INTEnableSystemMultiVectoredInt(); 766 | 767 | // Enable optimal performance 768 | SYSTEMConfigPerformance(GetSystemClock()); 769 | mOSCSetPBDIV(OSC_PB_DIV_1); // Use 1:1 CPU Core:Peripheral clocks 770 | 771 | // Disable JTAG port so we get our I/O pins back, but first 772 | // wait 50ms so if you want to reprogram the part with 773 | // JTAG, you'll still have a tiny window before JTAG goes away. 774 | // The PIC32 Starter Kit debuggers use JTAG and therefore must not 775 | // disable JTAG. 776 | DelayMs(50); 777 | #if !defined(__MPLAB_DEBUGGER_PIC32MXSK) && !defined(__MPLAB_DEBUGGER_FS2) 778 | DDPCONbits.JTAGEN = 0; 779 | #endif 780 | LED_PUT(0x00); // Turn the LEDs off 781 | 782 | CNPUESET = 0x0009E000; // Turn on weak pull ups on CN13, CN14, CN15, CN16, CN19 (RD5, RD7, RD13) is connected to buttons on PIC32 Starter Kit boards 783 | } 784 | #endif 785 | 786 | #if defined(__dsPIC33F__) || defined(__PIC24H__) 787 | // Crank up the core frequency 788 | PLLFBD = 38; // Multiply by 40 for 160MHz VCO output (8MHz XT oscillator) 789 | CLKDIV = 0x0000; // FRC: divide by 2, PLLPOST: divide by 2, PLLPRE: divide by 2 790 | 791 | // Port I/O 792 | AD1PCFGHbits.PCFG23 = 1; // Make RA7 (BUTTON1) a digital input 793 | AD1PCFGHbits.PCFG20 = 1; // Make RA12 (INT1) a digital input for MRF24WB0M PICtail Plus interrupt 794 | 795 | // ADC 796 | AD1CHS0 = 0; // Input to AN0 (potentiometer) 797 | AD1PCFGLbits.PCFG5 = 0; // Disable digital input on AN5 (potentiometer) 798 | AD1PCFGLbits.PCFG4 = 0; // Disable digital input on AN4 (TC1047A temp sensor) 799 | 800 | 801 | #elif defined(__dsPIC33E__)||defined(__PIC24E__) 802 | 803 | // Crank up the core frequency 804 | PLLFBD = 38; /* M = 30 */ 805 | CLKDIVbits.PLLPOST = 0; /* N1 = 2 */ 806 | CLKDIVbits.PLLPRE = 0; /* N2 = 2 */ 807 | OSCTUN = 0; 808 | 809 | /* Initiate Clock Switch to Primary 810 | * Oscillator with PLL (NOSC= 0x3)*/ 811 | __builtin_write_OSCCONH(0x03); 812 | __builtin_write_OSCCONL(0x01); 813 | // Disable Watch Dog Timer 814 | RCONbits.SWDTEN = 0; 815 | while (OSCCONbits.COSC != 0x3); 816 | while (_LOCK == 0); /* Wait for PLL lock at 60 MIPS */ 817 | // Port I/O 818 | ANSELAbits.ANSA7 = 0 ; //Make RA7 (BUTTON1) a digital input 819 | #if defined ENC100_INTERFACE_MODE > 0 820 | ANSELEbits.ANSE0 = 0; // Make these PMP pins as digital output when the interface is parallel. 821 | ANSELEbits.ANSE1 = 0; 822 | ANSELEbits.ANSE2 = 0; 823 | ANSELEbits.ANSE3 = 0; 824 | ANSELEbits.ANSE4 = 0; 825 | ANSELEbits.ANSE5 = 0; 826 | ANSELEbits.ANSE6 = 0; 827 | ANSELEbits.ANSE7 = 0; 828 | ANSELBbits.ANSB10 = 0; 829 | ANSELBbits.ANSB11 = 0; 830 | ANSELBbits.ANSB12 = 0; 831 | ANSELBbits.ANSB13 = 0; 832 | ANSELBbits.ANSB15 = 0; 833 | #endif 834 | 835 | ANSELEbits.ANSE8= 0 ; // Make RE8(INT1) a digital input for ZeroG ZG2100M PICtail 836 | 837 | AD1CHS0 = 0; // Input to AN0 (potentiometer) 838 | ANSELBbits.ANSB0= 1; // Input to AN0 (potentiometer) 839 | ANSELBbits.ANSB5= 1; // Disable digital input on AN5 (potentiometer) 840 | ANSELBbits.ANSB4= 1; // Disable digital input on AN4 (TC1047A temp sensor) 841 | 842 | ANSELDbits.ANSD7 =0; // Digital Pin Selection for S3(Pin 83) and S4(pin 84). 843 | ANSELDbits.ANSD6 =0; 844 | 845 | ANSELGbits.ANSG6 =0; // Enable Digital input for RG6 (SCK2) 846 | ANSELGbits.ANSG7 =0; // Enable Digital input for RG7 (SDI2) 847 | ANSELGbits.ANSG8 =0; // Enable Digital input for RG8 (SDO2) 848 | ANSELGbits.ANSG9 =0; // Enable Digital input for RG9 (CS) 849 | 850 | #if defined ENC100_INTERFACE_MODE == 0 // SPI Interface, UART can be used for debugging. Not allowed for other interfaces. 851 | RPOR9 = 0x0300; //RP101= U2TX 852 | RPINR19 = 0X0064; //RP100= U2RX 853 | #endif 854 | 855 | #if defined WF_CS_TRIS 856 | RPINR1bits.INT3R = 30; 857 | WF_CS_IO = 1; 858 | WF_CS_TRIS = 0; 859 | 860 | #endif 861 | 862 | #else //defined(__PIC24F__) || defined(__PIC32MX__) 863 | #if defined(__PIC24F__) 864 | CLKDIVbits.RCDIV = 0; // Set 1:1 8MHz FRC postscalar 865 | #endif 866 | 867 | // ADC 868 | #if defined(__PIC24FJ256DA210__) || defined(__PIC24FJ256GB210__) 869 | // Disable analog on all pins 870 | ANSA = 0x0000; 871 | ANSB = 0x0000; 872 | ANSC = 0x0000; 873 | ANSD = 0x0000; 874 | ANSE = 0x0000; 875 | ANSF = 0x0000; 876 | ANSG = 0x0000; 877 | #else 878 | AD1CHS = 0; // Input to AN0 (potentiometer) 879 | AD1PCFGbits.PCFG4 = 0; // Disable digital input on AN4 (TC1047A temp sensor) 880 | #if defined(__32MX460F512L__) || defined(__32MX795F512L__) // PIC32MX460F512L and PIC32MX795F512L PIMs has different pinout to accomodate USB module 881 | AD1PCFGbits.PCFG2 = 0; // Disable digital input on AN2 (potentiometer) 882 | #else 883 | AD1PCFGbits.PCFG5 = 0; // Disable digital input on AN5 (potentiometer) 884 | #endif 885 | #endif 886 | #endif 887 | 888 | // ADC 889 | AD1CON1 = 0x84E4; // Turn on, auto sample start, auto-convert, 12 bit mode (on parts with a 12bit A/D) 890 | AD1CON2 = 0x0404; // AVdd, AVss, int every 2 conversions, MUXA only, scan 891 | AD1CON3 = 0x1003; // 16 Tad auto-sample, Tad = 3*Tcy 892 | #if defined(__32MX460F512L__) || defined(__32MX795F512L__) // PIC32MX460F512L and PIC32MX795F512L PIMs has different pinout to accomodate USB module 893 | AD1CSSL = 1<<2; // Scan pot 894 | #else 895 | AD1CSSL = 1<<5; // Scan pot 896 | #endif 897 | 898 | // UART 899 | #if defined(STACK_USE_UART) 900 | 901 | #if defined(__PIC24E__) || defined(__dsPIC33E__) 902 | #if defined (ENC_CS_IO) || defined (WF_CS_IO) // UART to be used in case of ENC28J60 or MRF24WB0M 903 | __builtin_write_OSCCONL(OSCCON & 0xbf); 904 | RPOR9bits.RP101R = 3; //Map U2TX to RF5 905 | RPINR19bits.U2RXR = 0; 906 | RPINR19bits.U2RXR = 0x64; //Map U2RX to RF4 907 | __builtin_write_OSCCONL(OSCCON | 0x40); 908 | #endif 909 | #if(ENC100_INTERFACE_MODE == 0) // UART to be used only in case of SPI interface with ENC624Jxxx 910 | __builtin_write_OSCCONL(OSCCON & 0xbf); 911 | RPOR9bits.RP101R = 3; //Map U2TX to RF5 912 | RPINR19bits.U2RXR = 0; 913 | RPINR19bits.U2RXR = 0x64; //Map U2RX to RF4 914 | __builtin_write_OSCCONL(OSCCON | 0x40); 915 | 916 | #endif 917 | #endif 918 | 919 | UARTTX_TRIS = 0; 920 | UARTRX_TRIS = 1; 921 | UMODE = 0x8000; // Set UARTEN. Note: this must be done before setting UTXEN 922 | 923 | #if defined(__C30__) 924 | USTA = 0x0400; // UTXEN set 925 | #define CLOSEST_UBRG_VALUE ((GetPeripheralClock()+8ul*BAUD_RATE)/16/BAUD_RATE-1) 926 | #define BAUD_ACTUAL (GetPeripheralClock()/16/(CLOSEST_UBRG_VALUE+1)) 927 | #else //defined(__C32__) 928 | USTA = 0x00001400; // RXEN set, TXEN set 929 | #define CLOSEST_UBRG_VALUE ((GetPeripheralClock()+8ul*BAUD_RATE)/16/BAUD_RATE-1) 930 | #define BAUD_ACTUAL (GetPeripheralClock()/16/(CLOSEST_UBRG_VALUE+1)) 931 | #endif 932 | 933 | #define BAUD_ERROR ((BAUD_ACTUAL > BAUD_RATE) ? BAUD_ACTUAL-BAUD_RATE : BAUD_RATE-BAUD_ACTUAL) 934 | #define BAUD_ERROR_PRECENT ((BAUD_ERROR*100+BAUD_RATE/2)/BAUD_RATE) 935 | #if (BAUD_ERROR_PRECENT > 3) 936 | #warning UART frequency error is worse than 3% 937 | #elif (BAUD_ERROR_PRECENT > 2) 938 | #warning UART frequency error is worse than 2% 939 | #endif 940 | 941 | UBRG = CLOSEST_UBRG_VALUE; 942 | #endif 943 | 944 | #endif 945 | 946 | // Deassert all chip select lines so there isn't any problem with 947 | // initialization order. Ex: When ENC28J60 is on SPI2 with Explorer 16, 948 | // MAX3232 ROUT2 pin will drive RF12/U2CTS ENC28J60 CS line asserted, 949 | // preventing proper 25LC256 EEPROM operation. 950 | #if defined(ENC_CS_TRIS) 951 | ENC_CS_IO = 1; 952 | ENC_CS_TRIS = 0; 953 | #endif 954 | #if defined(ENC100_CS_TRIS) 955 | ENC100_CS_IO = (ENC100_INTERFACE_MODE == 0); 956 | ENC100_CS_TRIS = 0; 957 | #endif 958 | #if defined(EEPROM_CS_TRIS) 959 | EEPROM_CS_IO = 1; 960 | EEPROM_CS_TRIS = 0; 961 | #endif 962 | #if defined(SPIRAM_CS_TRIS) 963 | SPIRAM_CS_IO = 1; 964 | SPIRAM_CS_TRIS = 0; 965 | #endif 966 | #if defined(SPIFLASH_CS_TRIS) 967 | SPIFLASH_CS_IO = 1; 968 | SPIFLASH_CS_TRIS = 0; 969 | #endif 970 | #if defined(WF_CS_TRIS) 971 | WF_CS_IO = 1; 972 | WF_CS_TRIS = 0; 973 | #endif 974 | 975 | #if defined(PIC24FJ64GA004_PIM) 976 | __builtin_write_OSCCONL(OSCCON & 0xBF); // Unlock PPS 977 | 978 | // Remove some LED outputs to regain other functions 979 | LED1_TRIS = 1; // Multiplexed with BUTTON0 980 | LED5_TRIS = 1; // Multiplexed with EEPROM CS 981 | LED7_TRIS = 1; // Multiplexed with BUTTON1 982 | 983 | // Inputs 984 | RPINR19bits.U2RXR = 19; //U2RX = RP19 985 | RPINR22bits.SDI2R = 20; //SDI2 = RP20 986 | RPINR20bits.SDI1R = 17; //SDI1 = RP17 987 | 988 | // Outputs 989 | RPOR12bits.RP25R = U2TX_IO; //RP25 = U2TX 990 | RPOR12bits.RP24R = SCK2OUT_IO; //RP24 = SCK2 991 | RPOR10bits.RP21R = SDO2_IO; //RP21 = SDO2 992 | RPOR7bits.RP15R = SCK1OUT_IO; //RP15 = SCK1 993 | RPOR8bits.RP16R = SDO1_IO; //RP16 = SDO1 994 | 995 | AD1PCFG = 0xFFFF; //All digital inputs - POT and Temp are on same pin as SDO1/SDI1, which is needed for ENC28J60 commnications 996 | 997 | __builtin_write_OSCCONL(OSCCON | 0x40); // Lock PPS 998 | #endif 999 | 1000 | #if defined(__PIC24FJ256DA210__) 1001 | __builtin_write_OSCCONL(OSCCON & 0xBF); // Unlock PPS 1002 | 1003 | // Inputs 1004 | RPINR19bits.U2RXR = 11; // U2RX = RP11 1005 | RPINR20bits.SDI1R = 0; // SDI1 = RP0 1006 | RPINR0bits.INT1R = 34; // Assign RE9/RPI34 to INT1 (input) for MRF24WB0M Wi-Fi PICtail Plus interrupt 1007 | 1008 | // Outputs 1009 | RPOR8bits.RP16R = 5; // RP16 = U2TX 1010 | RPOR1bits.RP2R = 8; // RP2 = SCK1 1011 | RPOR0bits.RP1R = 7; // RP1 = SDO1 1012 | 1013 | __builtin_write_OSCCONL(OSCCON | 0x40); // Lock PPS 1014 | #endif 1015 | 1016 | #if defined(__PIC24FJ256GB110__) || defined(__PIC24FJ256GB210__) 1017 | __builtin_write_OSCCONL(OSCCON & 0xBF); // Unlock PPS 1018 | 1019 | // Configure SPI1 PPS pins (ENC28J60/ENCX24J600/MRF24WB0M or other PICtail Plus cards) 1020 | RPOR0bits.RP0R = 8; // Assign RP0 to SCK1 (output) 1021 | RPOR7bits.RP15R = 7; // Assign RP15 to SDO1 (output) 1022 | RPINR20bits.SDI1R = 23; // Assign RP23 to SDI1 (input) 1023 | 1024 | // Configure SPI2 PPS pins (25LC256 EEPROM on Explorer 16) 1025 | RPOR10bits.RP21R = 11; // Assign RG6/RP21 to SCK2 (output) 1026 | RPOR9bits.RP19R = 10; // Assign RG8/RP19 to SDO2 (output) 1027 | RPINR22bits.SDI2R = 26; // Assign RG7/RP26 to SDI2 (input) 1028 | 1029 | // Configure UART2 PPS pins (MAX3232 on Explorer 16) 1030 | #if !defined(ENC100_INTERFACE_MODE) || (ENC100_INTERFACE_MODE == 0) || defined(ENC100_PSP_USE_INDIRECT_RAM_ADDRESSING) 1031 | RPINR19bits.U2RXR = 10; // Assign RF4/RP10 to U2RX (input) 1032 | RPOR8bits.RP17R = 5; // Assign RF5/RP17 to U2TX (output) 1033 | #endif 1034 | 1035 | // Configure INT1 PPS pin (MRF24WB0M Wi-Fi PICtail Plus interrupt signal when in SPI slot 1) 1036 | RPINR0bits.INT1R = 33; // Assign RE8/RPI33 to INT1 (input) 1037 | 1038 | // Configure INT3 PPS pin (MRF24WB0M Wi-Fi PICtail Plus interrupt signal when in SPI slot 2) 1039 | RPINR1bits.INT3R = 40; // Assign RC3/RPI40 to INT3 (input) 1040 | 1041 | __builtin_write_OSCCONL(OSCCON | 0x40); // Lock PPS 1042 | #endif 1043 | 1044 | #if defined(__PIC24FJ256GA110__) 1045 | __builtin_write_OSCCONL(OSCCON & 0xBF); // Unlock PPS 1046 | 1047 | // Configure SPI2 PPS pins (25LC256 EEPROM on Explorer 16 and ENC28J60/ENCX24J600/MRF24WB0M or other PICtail Plus cards) 1048 | // Note that the ENC28J60/ENCX24J600/MRF24WB0M PICtails SPI PICtails must be inserted into the middle SPI2 socket, not the topmost SPI1 slot as normal. This is because PIC24FJ256GA110 A3 silicon has an input-only RPI PPS pin in the ordinary SCK1 location. Silicon rev A5 has this fixed, but for simplicity all demos will assume we are using SPI2. 1049 | RPOR10bits.RP21R = 11; // Assign RG6/RP21 to SCK2 (output) 1050 | RPOR9bits.RP19R = 10; // Assign RG8/RP19 to SDO2 (output) 1051 | RPINR22bits.SDI2R = 26; // Assign RG7/RP26 to SDI2 (input) 1052 | 1053 | // Configure UART2 PPS pins (MAX3232 on Explorer 16) 1054 | RPINR19bits.U2RXR = 10; // Assign RF4/RP10 to U2RX (input) 1055 | RPOR8bits.RP17R = 5; // Assign RF5/RP17 to U2TX (output) 1056 | 1057 | // Configure INT3 PPS pin (MRF24WB0M PICtail Plus interrupt signal) 1058 | RPINR1bits.INT3R = 36; // Assign RA14/RPI36 to INT3 (input) 1059 | 1060 | __builtin_write_OSCCONL(OSCCON | 0x40); // Lock PPS 1061 | #endif 1062 | 1063 | 1064 | #if defined(DSPICDEM11) 1065 | // Deselect the LCD controller (PIC18F252 onboard) to ensure there is no SPI2 contention 1066 | LCDCTRL_CS_TRIS = 0; 1067 | LCDCTRL_CS_IO = 1; 1068 | 1069 | // Hold the codec in reset to ensure there is no SPI2 contention 1070 | CODEC_RST_TRIS = 0; 1071 | CODEC_RST_IO = 0; 1072 | #endif 1073 | 1074 | #if defined(SPIRAM_CS_TRIS) 1075 | SPIRAMInit(); 1076 | #endif 1077 | #if defined(EEPROM_CS_TRIS) 1078 | XEEInit(); 1079 | #endif 1080 | #if defined(SPIFLASH_CS_TRIS) 1081 | SPIFlashInit(); 1082 | #endif 1083 | } 1084 | 1085 | /********************************************************************* 1086 | * Function: void InitAppConfig(void) 1087 | * 1088 | * PreCondition: MPFSInit() is already called. 1089 | * 1090 | * Input: None 1091 | * 1092 | * Output: Write/Read non-volatile config variables. 1093 | * 1094 | * Side Effects: None 1095 | * 1096 | * Overview: None 1097 | * 1098 | * Note: None 1099 | ********************************************************************/ 1100 | // MAC Address Serialization using a MPLAB PM3 Programmer and 1101 | // Serialized Quick Turn Programming (SQTP). 1102 | // The advantage of using SQTP for programming the MAC Address is it 1103 | // allows you to auto-increment the MAC address without recompiling 1104 | // the code for each unit. To use SQTP, the MAC address must be fixed 1105 | // at a specific location in program memory. Uncomment these two pragmas 1106 | // that locate the MAC address at 0x1FFF0. Syntax below is for MPLAB C 1107 | // Compiler for PIC18 MCUs. Syntax will vary for other compilers. 1108 | //#pragma romdata MACROM=0x1FFF0 1109 | static ROM BYTE SerializedMACAddress[6] = {MY_DEFAULT_MAC_BYTE1, MY_DEFAULT_MAC_BYTE2, MY_DEFAULT_MAC_BYTE3, MY_DEFAULT_MAC_BYTE4, MY_DEFAULT_MAC_BYTE5, MY_DEFAULT_MAC_BYTE6}; 1110 | //#pragma romdata 1111 | 1112 | static void InitAppConfig(void) 1113 | { 1114 | #if defined(EEPROM_CS_TRIS) || defined(SPIFLASH_CS_TRIS) 1115 | unsigned char vNeedToSaveDefaults = 0; 1116 | #endif 1117 | 1118 | while(1) 1119 | { 1120 | // Start out zeroing all AppConfig bytes to ensure all fields are 1121 | // deterministic for checksum generation 1122 | memset((void*)&AppConfig, 0x00, sizeof(AppConfig)); 1123 | 1124 | AppConfig.Flags.bIsDHCPEnabled = TRUE; 1125 | AppConfig.Flags.bInConfigMode = TRUE; 1126 | memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr)); 1127 | // { 1128 | // _prog_addressT MACAddressAddress; 1129 | // MACAddressAddress.next = 0x157F8; 1130 | // _memcpy_p2d24((char*)&AppConfig.MyMACAddr, MACAddressAddress, sizeof(AppConfig.MyMACAddr)); 1131 | // } 1132 | AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul; 1133 | AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val; 1134 | AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul; 1135 | AppConfig.DefaultMask.Val = AppConfig.MyMask.Val; 1136 | AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul; 1137 | AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul; 1138 | AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul; 1139 | 1140 | 1141 | // SNMP Community String configuration 1142 | #if defined(STACK_USE_SNMP_SERVER) 1143 | { 1144 | BYTE i; 1145 | static ROM char * ROM cReadCommunities[] = SNMP_READ_COMMUNITIES; 1146 | static ROM char * ROM cWriteCommunities[] = SNMP_WRITE_COMMUNITIES; 1147 | ROM char * strCommunity; 1148 | 1149 | for(i = 0; i < SNMP_MAX_COMMUNITY_SUPPORT; i++) 1150 | { 1151 | // Get a pointer to the next community string 1152 | strCommunity = cReadCommunities[i]; 1153 | if(i >= sizeof(cReadCommunities)/sizeof(cReadCommunities[0])) 1154 | strCommunity = ""; 1155 | 1156 | // Ensure we don't buffer overflow. If your code gets stuck here, 1157 | // it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 1158 | // is either too small or one of your community string lengths 1159 | // (SNMP_READ_COMMUNITIES) are too large. Fix either. 1160 | if(strlenpgm(strCommunity) >= sizeof(AppConfig.readCommunity[0])) 1161 | while(1); 1162 | 1163 | // Copy string into AppConfig 1164 | strcpypgm2ram((char*)AppConfig.readCommunity[i], strCommunity); 1165 | 1166 | // Get a pointer to the next community string 1167 | strCommunity = cWriteCommunities[i]; 1168 | if(i >= sizeof(cWriteCommunities)/sizeof(cWriteCommunities[0])) 1169 | strCommunity = ""; 1170 | 1171 | // Ensure we don't buffer overflow. If your code gets stuck here, 1172 | // it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 1173 | // is either too small or one of your community string lengths 1174 | // (SNMP_WRITE_COMMUNITIES) are too large. Fix either. 1175 | if(strlenpgm(strCommunity) >= sizeof(AppConfig.writeCommunity[0])) 1176 | while(1); 1177 | 1178 | // Copy string into AppConfig 1179 | strcpypgm2ram((char*)AppConfig.writeCommunity[i], strCommunity); 1180 | } 1181 | } 1182 | #endif 1183 | 1184 | // Load the default NetBIOS Host Name 1185 | memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 16); 1186 | FormatNetBIOSName(AppConfig.NetBIOSName); 1187 | 1188 | #if defined(WF_CS_TRIS) 1189 | // Load the default SSID Name 1190 | WF_ASSERT(sizeof(MY_DEFAULT_SSID_NAME) <= sizeof(AppConfig.MySSID)); 1191 | memcpypgm2ram(AppConfig.MySSID, (ROM void*)MY_DEFAULT_SSID_NAME, sizeof(MY_DEFAULT_SSID_NAME)); 1192 | AppConfig.SsidLength = sizeof(MY_DEFAULT_SSID_NAME) - 1; 1193 | 1194 | AppConfig.SecurityMode = MY_DEFAULT_WIFI_SECURITY_MODE; 1195 | AppConfig.WepKeyIndex = MY_DEFAULT_WEP_KEY_INDEX; 1196 | 1197 | #if (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_OPEN) 1198 | memset(AppConfig.SecurityKey, 0x00, sizeof(AppConfig.SecurityKey)); 1199 | AppConfig.SecurityKeyLength = 0; 1200 | 1201 | #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WEP_40 1202 | memcpypgm2ram(AppConfig.SecurityKey, (ROM void*)MY_DEFAULT_WEP_KEYS_40, sizeof(MY_DEFAULT_WEP_KEYS_40) - 1); 1203 | AppConfig.SecurityKeyLength = sizeof(MY_DEFAULT_WEP_KEYS_40) - 1; 1204 | 1205 | #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WEP_104 1206 | memcpypgm2ram(AppConfig.SecurityKey, (ROM void*)MY_DEFAULT_WEP_KEYS_104, sizeof(MY_DEFAULT_WEP_KEYS_104) - 1); 1207 | AppConfig.SecurityKeyLength = sizeof(MY_DEFAULT_WEP_KEYS_104) - 1; 1208 | 1209 | #elif (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_WITH_KEY) || \ 1210 | (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA2_WITH_KEY) || \ 1211 | (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_AUTO_WITH_KEY) 1212 | memcpypgm2ram(AppConfig.SecurityKey, (ROM void*)MY_DEFAULT_PSK, sizeof(MY_DEFAULT_PSK) - 1); 1213 | AppConfig.SecurityKeyLength = sizeof(MY_DEFAULT_PSK) - 1; 1214 | 1215 | #elif (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_WITH_PASS_PHRASE) || \ 1216 | (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA2_WITH_PASS_PHRASE) || \ 1217 | (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE) 1218 | memcpypgm2ram(AppConfig.SecurityKey, (ROM void*)MY_DEFAULT_PSK_PHRASE, sizeof(MY_DEFAULT_PSK_PHRASE) - 1); 1219 | AppConfig.SecurityKeyLength = sizeof(MY_DEFAULT_PSK_PHRASE) - 1; 1220 | 1221 | #else 1222 | #error "No security defined" 1223 | #endif /* MY_DEFAULT_WIFI_SECURITY_MODE */ 1224 | 1225 | #endif 1226 | 1227 | // Compute the checksum of the AppConfig defaults as loaded from ROM 1228 | wOriginalAppConfigChecksum = CalcIPChecksum((BYTE*)&AppConfig, sizeof(AppConfig)); 1229 | 1230 | #if defined(EEPROM_CS_TRIS) || defined(SPIFLASH_CS_TRIS) 1231 | { 1232 | NVM_VALIDATION_STRUCT NVMValidationStruct; 1233 | 1234 | // Check to see if we have a flag set indicating that we need to 1235 | // save the ROM default AppConfig values. 1236 | if(vNeedToSaveDefaults) 1237 | SaveAppConfig(&AppConfig); 1238 | 1239 | // Read the NVMValidation record and AppConfig struct out of EEPROM/Flash 1240 | #if defined(EEPROM_CS_TRIS) 1241 | { 1242 | XEEReadArray(0x0000, (BYTE*)&NVMValidationStruct, sizeof(NVMValidationStruct)); 1243 | XEEReadArray(sizeof(NVMValidationStruct), (BYTE*)&AppConfig, sizeof(AppConfig)); 1244 | } 1245 | #elif defined(SPIFLASH_CS_TRIS) 1246 | { 1247 | SPIFlashReadArray(0x0000, (BYTE*)&NVMValidationStruct, sizeof(NVMValidationStruct)); 1248 | SPIFlashReadArray(sizeof(NVMValidationStruct), (BYTE*)&AppConfig, sizeof(AppConfig)); 1249 | } 1250 | #endif 1251 | 1252 | // Check EEPROM/Flash validitity. If it isn't valid, set a flag so 1253 | // that we will save the ROM default values on the next loop 1254 | // iteration. 1255 | if((NVMValidationStruct.wConfigurationLength != sizeof(AppConfig)) || 1256 | (NVMValidationStruct.wOriginalChecksum != wOriginalAppConfigChecksum) || 1257 | (NVMValidationStruct.wCurrentChecksum != CalcIPChecksum((BYTE*)&AppConfig, sizeof(AppConfig)))) 1258 | { 1259 | // Check to ensure that the vNeedToSaveDefaults flag is zero, 1260 | // indicating that this is the first iteration through the do 1261 | // loop. If we have already saved the defaults once and the 1262 | // EEPROM/Flash still doesn't pass the validity check, then it 1263 | // means we aren't successfully reading or writing to the 1264 | // EEPROM/Flash. This means you have a hardware error and/or 1265 | // SPI configuration error. 1266 | if(vNeedToSaveDefaults) 1267 | { 1268 | while(1); 1269 | } 1270 | 1271 | // Set flag and restart loop to load ROM defaults and save them 1272 | vNeedToSaveDefaults = 1; 1273 | continue; 1274 | } 1275 | 1276 | // If we get down here, it means the EEPROM/Flash has valid contents 1277 | // and either matches the ROM defaults or previously matched and 1278 | // was run-time reconfigured by the user. In this case, we shall 1279 | // use the contents loaded from EEPROM/Flash. 1280 | break; 1281 | } 1282 | #endif 1283 | break; 1284 | } 1285 | } 1286 | 1287 | #if defined(EEPROM_CS_TRIS) || defined(SPIFLASH_CS_TRIS) 1288 | void SaveAppConfig(const APP_CONFIG *ptrAppConfig) 1289 | { 1290 | NVM_VALIDATION_STRUCT NVMValidationStruct; 1291 | 1292 | // Ensure adequate space has been reserved in non-volatile storage to 1293 | // store the entire AppConfig structure. If you get stuck in this while(1) 1294 | // trap, it means you have a design time misconfiguration in TCPIPConfig.h. 1295 | // You must increase MPFS_RESERVE_BLOCK to allocate more space. 1296 | #if defined(STACK_USE_MPFS2) 1297 | if(sizeof(NVMValidationStruct) + sizeof(AppConfig) > MPFS_RESERVE_BLOCK) 1298 | while(1); 1299 | #endif 1300 | 1301 | // Get proper values for the validation structure indicating that we can use 1302 | // these EEPROM/Flash contents on future boot ups 1303 | NVMValidationStruct.wOriginalChecksum = wOriginalAppConfigChecksum; 1304 | NVMValidationStruct.wCurrentChecksum = CalcIPChecksum((BYTE*)ptrAppConfig, sizeof(APP_CONFIG)); 1305 | NVMValidationStruct.wConfigurationLength = sizeof(APP_CONFIG); 1306 | 1307 | // Write the validation struct and current AppConfig contents to EEPROM/Flash 1308 | #if defined(EEPROM_CS_TRIS) 1309 | XEEBeginWrite(0x0000); 1310 | XEEWriteArray((BYTE*)&NVMValidationStruct, sizeof(NVMValidationStruct)); 1311 | XEEWriteArray((BYTE*)ptrAppConfig, sizeof(APP_CONFIG)); 1312 | #else 1313 | SPIFlashBeginWrite(0x0000); 1314 | SPIFlashWriteArray((BYTE*)&NVMValidationStruct, sizeof(NVMValidationStruct)); 1315 | SPIFlashWriteArray((BYTE*)ptrAppConfig, sizeof(APP_CONFIG)); 1316 | #endif 1317 | } 1318 | #endif 1319 | 1320 | --------------------------------------------------------------------------------