/********************************************************************* * * Modtronix Example Web Server Application using Microchip TCP/IP Stack * ********************************************************************* * FileName: WebSrvr.c * Dependencies: string.H * usart.h * stacktsk.h * Tick.h * http.h * MPFS.h * Processor: PIC18 * Complier: MCC18 v1.00.50 or higher * HITECH PICC-18 V8.35PL3 or higher * Company: Microchip Technology, Inc. * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the Company) for its PICmicro® Microcontroller is intended and * supplied to you, the Company’s customer, for use solely and * exclusively on Microchip PICmicro Microcontroller products. The * software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN AS IS CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * * HiTech PICC18 Compiler Options excluding device selection: * -FAKELOCAL -G -O -Zg -E -C * ********************************************************************** * File History * * 2004--2-15, David Hosken (DH): * - Original (Rev. 1.0) * 2009-05-29, David Hosken (DH): * - Added code for watchdog timer, and alive counters * - Fixed bug initializing CPU ports. This bug could have caused very short * micro-second spikes on IO ports at start up. Sequence of calling appcfgCpuIO() * and appcfgCpuIOValues() functions were fixed. *********************************************************************/ /*********************************** * USGS history * This is branched from the best working version prior to delivery of * the controller board by Bradley and Duester * Note clamp circuit does not work. * 7/1/2011 * Enable USART 2 * fix some issues with RB0 trip status input not responding to patch status * 7/6/2011 * change the status of RB3 to be set to 0 on startup, this will act like a clamp (parking brake) * 7/7/2011 * set port F to 0x73 on startup to make sure control voltage is in dead band * 7/9/2011 * clean up initializations * slow down IG20 acquisition rate * set "zero point" of motor control output to 127 = 0x7F = 0b01111111 * 7/11/2011 * move initializations to where they should be - in initializeboard function * verify that pullups are DISABLED * 7/13/2011 * change trip indicator from B0 to C5 - now it works. * call this stable version 1.0 * 7/14/2011 * implement an ARP recheck cycle every 60 sec in case this is needed * 7/19/2011 * Restructure how I set up the UDP message so that it can be sent to two established UDP sockets * put all the data, even the non-serial stuff, in the ser2UDP buffer * Version 2.0 * now, attempt two UDP ports simultaneously. Succeeded. * Version 2.1 * provide a short IG20 data frame capture, time only, for testing * Version 2.2 * real IG20 data frame capture * Version 2.3 7/31/2011 * Change the placeholder "A" in the UDP output to show armed status of trip * Version 2.4 8/1/2011 * Change the default IP's to what is needed for the WHOI network * Version 2.5 8/15/2011 * Add port F value to UDP output * Version 2.6 8/23/2011 * Add a startup delay to ensure that ARP check happens when the Moxa is alive */ /* * Following define uniquely deines this file as main * entry/application In whole project, there should only be one such * definition and application file must define AppConfig variable as * described below. */ #define THIS_IS_STACK_APPLICATION #include #include "projdefs.h" #include "debug.h" #include "busser1.h" #include "busser2.h" #include "sercfg.h" //#include "appcfg.h" #include "httpexec.h" #include "cmd.h" #include "event.h" #include "lcd2s.h" #include "ior5e.h" #include "mxd2r.h" #include "buses.h" #include "io.h" #include "net\cpuconf.h" #include "net\stacktsk.h" #include "net\fsee.h" #include "net\tick.h" #include "net\helpers.h" #include "net\i2c.h" #if defined(STACK_USE_DHCP) #include "net\dhcp.h" #endif #if defined(STACK_USE_HTTP_SERVER) #include "net\http.h" #endif #if defined(STACK_USE_FTP_SERVER) #include "net\ftp.h" #endif #if defined(STACK_USE_ANNOUNCE) #include "net\announce.h" #endif #if defined(STACK_USE_NBNS) #include "net\nbns.h" #endif //USGS includes #include "net\arp.h" #include "net\arptsk.h" // end USGS ///////////////////////////////////////////////// //Debug defines #define debugPutMsg(msgCode) debugPut2Bytes(0xD6, msgCode) #define debugPutMsgRomStr(msgCode, strStr) debugMsgRomStr(0xD6, msgCode, msgStr) ///////////////////////////////////////////////// //Global variables used for alive counters. BYTE aliveCntrMain; //Alive counter must be reset each couple of ms to prevent board reset. Set to 0xff to disable. BOOL aliveCntrDec; ///////////////////////////////////////////////// //Version number // - n = major part, and can be 1 or 2 digets long // - mm is minor part, and must be 2 digets long! ROM char APP_VER_STR[] = "V3.10"; BYTE myDHCPBindCount = 0xff; #if !defined(STACK_USE_DHCP) //If DHCP is not enabled, force DHCP update. #define DHCPBindCount 1 #endif static void InitializeBoard(void); static void ProcessIO(void); // -------USGS defines static UDP_SOCKET udpSocketUser0 = INVALID_UDP_SOCKET; static UDP_SOCKET udpSocketUser1 = INVALID_UDP_SOCKET; //UDP State machine for ARP resolution #define SM_UDP_SEND_ARP 0 #define SM_UDP_WAIT_RESOLVE 1 #define SM_UDP_RESOLVED 2 #define SM_UDP_SENT 3 static BYTE smUdp0 = SM_UDP_SEND_ARP; #ifdef DO2SOCKETS static BYTE smUdp1 = SM_UDP_SEND_ARP; #endif TICK8 tsecWait = 0; static BYTE bufSer2UDP[BUF_SER2UDP_MAXSIZE]; //Buffer of received bytes from USART that have to be TXed via UDP BYTE bytesInSer2UDP = 0; //How many bytes have been received that are to be send via UDP static BYTE USARTGetIG20(char *, BYTE); // USART 1 J2 static BYTE USART2GetIG20(char *, BYTE); // USART 2 J1 //unsigned int calcCRC(const unsigned char *pBuffer, unsigned int bufferSize); unsigned int calcCRC(BYTE *pBuffer, unsigned int bufferSize); // end USGS ///////////////////////////////////////////////// //High Interrupt ISR #if defined(MCHP_C18) #pragma interrupt HighISR void HighISR(void) #elif defined(HITECH_C18) #if defined(STACK_USE_SLIP) extern void MACISR(void); #endif void interrupt HighISR(void) #endif { ///////////////////////////////////////////////// //TMR0 is used for the ticks if (INTCON_TMR0IF) { TickUpdate(); #if defined(STACK_USE_SLIP) MACISR(); #endif INTCON_TMR0IF = 0; } ///////////////////////////////////////////////// //USART1 if(PIR1_RCIF && PIE1_RCIE) //USART1 Receive { serRxIsr(); } //USART1 Transmit if(PIR1_TXIF && PIE1_TXIE) { serTxIsr(); } ///////////////////////////////////////////////// //USART2 if(PIR3_RC2IF && PIE3_RC2IE) //USART1 Receive { ser2RxIsr(); } //USART2 Transmit if(PIR3_TX2IF && PIE3_TX2IE) { ser2TxIsr(); } } #if defined(MCHP_C18) #pragma code highVector=HIVECTOR_ADR void HighVector (void) { _asm goto HighISR _endasm } #pragma code /* return to default code section */ #endif /* * Fast User process. Place all high priority code that has to be called often * in this function. * * !!!!! IMPORTANT !!!!! * This function is called often, and should be very fast! */ void fastUserProcess(void) { T1CON_RD16 = 0; //Enable reading TMR1L and TMR1H individually //Decrement all alive counters every 26.2144ms x 2 = 52.42ms. //Timer1 is a free running timer that is incremented every 800ns. Bit 7 of TMR1H is toggled every 3.2512ms. if (TMR1H & 0x80) { if (aliveCntrDec) { aliveCntrDec = 0; //Decrement all alive counters. If alive counter is 0xff, it is disabled if ((aliveCntrMain!=0xff) && (aliveCntrMain!=0)) aliveCntrMain--; } } else aliveCntrDec=1; //Only clear watchdog timer if no alive counters are 0 if (aliveCntrMain!=0) { CLRWDT(); } } /* * Main entry point. */ void main(void) { //USGS define BYTE count = 0; char buf[5]; TICK8 tsec8ARPtimeout = 0; TICK16 tsec16ARPrecheck = 0; NODE_INFO udpServerNode0; #ifdef DO2SOCKETS NODE_INFO udpServerNode1; #endif // end USGS define static TICK8 t = 0; static BYTE testLED; testLED = 1; //Set SWDTEN bit, this will enable the watch dog timer WDTCON_SWDTEN = 1; aliveCntrMain = 0xff; //Disable alive counter during initialization. Setting to 0xff disables it. //Initialize any application specific hardware. InitializeBoard(); //Initialize all stack related components. Following steps must //be performed for all applications using PICmicro TCP/IP Stack. TickInit(); //Initialize buses busInit(); // //Initialize serial ports early, because they could be required for debugging if (appcfgGetc(APPCFG_USART1_CFG & APPCFG_USART_ENABLE)) { appcfgUSART(); //Configure the USART1 } if (appcfgGetc(APPCFG_USART2_CFG & APPCFG_USART_ENABLE)) { appcfgUSART2(); //Configure the USART2 } //After initializing all modules that use interrupts, enable global interrupts INTCON_GIEH = 1; INTCON_GIEL = 1; //Initialize file system. fsysInit(); //Intialize HTTP Execution unit htpexecInit(); //Initialize Stack and application related NV variables. appcfgInit(); //First call appcfgCpuIOValues() and then only appcfgCpuIO()!!! This ensures the value are set, before enabling ports appcfgCpuIOValues(); //Configure the CPU's I/O port pin default values appcfgCpuIO(); //Configure the CPU's I/O port pin directions - input or output appcfgADC(); //Configure ADC unit appcfgPWM(); //Configure PWM Channels //Serial configuration menu - display it for configured time and allow user to enter configuration menu scfInit(appcfgGetc(APPCFG_STARTUP_SER_DLY)); //LCD Display Initialize lcdInit(); //Initialize expansion board appcfgXboard(); StackInit(); #if defined(STACK_USE_HTTP_SERVER) HTTPInit(); #endif #if defined(STACK_USE_FTP_SERVER) FTPInit(); #endif //Intialise network componet of buses - only call after StackInit()! busNetInit(); //Initializes events. evtInit(); //Initializes "UDP Command Port" and "UDP Even Port". cmdInit(); ioInit(); #if (DEBUG_MAIN >= LOG_DEBUG) debugPutMsg(1); //@mxd:1:Starting main loop #endif // --------- USGS initializations PORTC_RC0 = 1; // OK to turn on the accelerometer - after the stratup menu in case // we are using USART1 // note that the check ARP process is enough time to let the accelerometer boot... serPutByte('\n'); serPutByte('V'); serPutByte(USGS_VERSION1); serPutByte('.'); serPutByte(USGS_VERSION2); #if FAKE_IG20 serPutByte('\n'); serPutByte('F'); serPutByte('I'); serPutByte('G'); #endif #if FAKE_A2D serPutByte('\n'); serPutByte('F'); serPutByte('A'); serPutByte('2'); serPutByte('D'); #endif /* open UDP socket #0 for USGS work * Modronix local port 54127 * remote (PC or Moxa) port 54128 * this code tries to resolve ARP for alimited time and then goes ahead. */ // #define DEFAULT_BUS_UDP1PORT (54125ul) // set in projdefs.h //udpSocketUser0 = UDPOpen(54127, &udpServerNode0, 54128); udpServerNode0.IPAddr.v[0] = MOXA_DEST_ADDR0; // set in projdefs.h udpServerNode0.IPAddr.v[1] = MOXA_DEST_ADDR1; udpServerNode0.IPAddr.v[2] = MOXA_DEST_ADDR2; udpServerNode0.IPAddr.v[3] = MOXA_DEST_ADDR3; serPutByte('\n'); serPutByte('d');serPutByte('e'); serPutByte('s');serPutByte('t'); serPutByte('0'); serPutByte(':'); //serPutByte(MOXA_DEST_ADDR0); serPutByte(MOXA_DEST_ADDR1);serPutByte(MOXA_DEST_ADDR2); serPutByte(MOXA_DEST_ADDR3); scfDisplayIPValue(&udpServerNode0.IPAddr); // open without resolving ARP udpSocketUser0 = UDPOpen(DEFAULT_BUS_UDP1PORT, &udpServerNode0, DEFAULT_MOXA_UDPPORT); serPutByte('U'); serPutByte('D');serPutByte('P'); serPutByte('o');serPutByte('p'); serPutByte('e'); serPutByte('n'); /* // this does not work 8/21/2011 - tried to avoid the ARP check - causes endless reboot if (!CHECK_ARP_AT_STARTUP){ UDPSocketInfo[udpSocketUser0].remoteNode = udpServerNode0; UDPFlush(); } */ //An error occurred during the UDPOpen() function if (udpSocketUser0 == INVALID_UDP_SOCKET) { serPutByte('B'); serPutByte('a');serPutByte('d'); serPutByte('s');serPutByte('k'); serPutByte('t'); } else { serPutByte('O'); serPutByte('K');serPutByte('-'); serPutByte('s');serPutByte('k'); serPutByte('t'); if (UDPIsPutReady(udpSocketUser0)) { UDPPut('U'); UDPPut('D'); UDPPut('P'); UDPPut(' '); // put data in buffer UDPPut('R'); UDPPut('e'); UDPPut('a'); UDPPut('d'); UDPPut('y'); // put data in buffer UDPPut(' '); UDPPut('V'); UDPPut(USGS_VERSION1); UDPPut('.'); UDPPut(USGS_VERSION2); UDPFlush(); // send contents and clear } } if (CHECK_ARP_AT_STARTUP) { // first, we wait to make sure the Moxa is awake to respond if (UDPIsPutReady(udpSocketUser0)) { UDPPut('d'); UDPPut('e'); UDPPut('l'); UDPPut('a'); UDPPut('y'); UDPPut('2'); UDPPut('A'); UDPPut('R'); UDPPut('P'); UDPPut('-'); // put data in buffer UDPFlush(); // send contents and clear } // unsigned char only goes to 255 so repeat! serPutByte('w'); serPutByte('a');serPutByte('i'); serPutByte('t'); itoa((unsigned int)DELAY_TO_ARP, buf); serPutString((BYTE *)buf); for (count = DELAY_TO_ARP; count--; count <=0) { DelayMs(250); // DelayMs executes fast user process so this should be OK DelayMs(250); // doing it 4 times so each loop is 1 sec DelayMs(250); // crude but effective & allows a status UDP DelayMs(250); itoa((unsigned int)count, buf); serPutString((BYTE *)buf); if (UDPIsPutReady(udpSocketUser0)) { UDPPut('d'); UDPPut('e'); UDPPut('l'); UDPPut('a'); UDPPut('y'); UDPPut('2'); UDPPut('A'); UDPPut('R'); UDPPut('P'); UDPPut(count); // put data in buffer UDPFlush(); // send contents and clear } } // open resolving ARP tsec8ARPtimeout = TickGet8bitSec(); // we don't want this ARP thing to go on too long // during startup we can be generaous, though sometimes the watchdog will reboot while(TickGetDiff8bitSec(tsec8ARPtimeout) <= (TICK8)ARP_TIMEOUT_AT_STARTUP) { switch (smUdp0) { case SM_UDP_SEND_ARP: if (ARPIsTxReady()) { //Remember when we sent last request tsecWait = TickGet8bitSec(); //Send ARP request for given IP address ARPResolve(&udpServerNode0.IPAddr); smUdp0 = SM_UDP_WAIT_RESOLVE; serPutByte('\n'); serPutByte('A'); serPutByte('R'); serPutByte('P'); serPutByte('-'); } break; case SM_UDP_WAIT_RESOLVE: //The IP address has been resolved, we now have the MAC address of the //node at 10.1.0.101 if (ARPIsResolved(&udpServerNode0.IPAddr, &udpServerNode0.MACAddr)) { smUdp0 = SM_UDP_RESOLVED; udpSocketUser0 = UDPOpen(DEFAULT_BUS_UDP1PORT, &udpServerNode0, DEFAULT_MOXA_UDPPORT); serPutByte('\n'); serPutByte('r'); serPutByte('e'); serPutByte('s'); serPutByte('v'); serPutByte('d'); } //If not resolved after 2 seconds, send next request else { if (TickGetDiff8bitSec(tsecWait) >= (TICK8)2) { smUdp0 = SM_UDP_SEND_ARP; serPutByte('\n'); serPutByte('w'); serPutByte('a'); serPutByte('i'); serPutByte('t'); } } break; case SM_UDP_RESOLVED: //Checks if there is a transmit buffer ready for accepting data if (UDPIsPutReady(udpSocketUser0)) { //Send a UDP Datagram with "Hello" UDPPut('H'); UDPPut('e'); UDPPut('l'); UDPPut('l'); UDPPut('o'); //Send contents of transmit buffer, and free buffer UDPFlush(); smUdp0 = SM_UDP_SENT; //Set to "message sent" state } break; case SM_UDP_SENT: //Message sent state. If the user wants to resend the message, smUdp0 must be reset //to SM_UDP_RESOLVED break; } //This task performs normal stack task including checking for incoming //packet, type of packet and calling appropriate stack entity to //process it. StackTask(); } if (smUdp0 != SM_UDP_RESOLVED) { serPutByte('\n'); serPutByte('A'); serPutByte('R'); serPutByte('P'); serPutByte('n'); serPutByte('o'); } } else { // need to give acceleraometer time to start up tsec8ARPtimeout = TickGet8bitSec(); while(TickGetDiff8bitSec(tsec8ARPtimeout) <= (TICK8)ARP_TIMEOUT_AT_STARTUP) { // do nothing. } } #ifdef DO2SOCKETS /* open UDP socket #1 for USGS work * Modronix local port 54127 * remote (PC or Moxa) port 54128 * this code tries to resolve ARP for alimited time and then goes ahead. */ // #define DEFAULT_BUS_UDP1PORT (54125ul) // set in projdefs.h //udpServerNode1 = UDPOpen(54127, &udpServerNode1, 54128); udpServerNode1.IPAddr.v[0] = MOXA_DEST_ADDR0; // set in projdefs.h udpServerNode1.IPAddr.v[1] = MOXA_DEST_ADDR1; udpServerNode1.IPAddr.v[2] = MOXA_DEST_ADDR2; udpServerNode1.IPAddr.v[3] = MOXA_DEST_ADDR3; udpServerNode1.IPAddr.v[3] += (BYTE)1; serPutByte('\n'); serPutByte('d');serPutByte('e'); serPutByte('s');serPutByte('t'); serPutByte('1'); serPutByte(':'); //serPutByte(MOXA_DEST_ADDR0); serPutByte(MOXA_DEST_ADDR1);serPutByte(MOXA_DEST_ADDR2); serPutByte(MOXA_DEST_ADDR3); scfDisplayIPValue(&udpServerNode1.IPAddr); // open without resolving ARP udpSocketUser1 = UDPOpen(DEFAULT_BUS_UDP1PORT, &udpServerNode1, DEFAULT_MOXA_UDPPORT); serPutByte('U'); serPutByte('D');serPutByte('P'); serPutByte('o');serPutByte('p'); serPutByte('e'); serPutByte('n'); //An error occurred during the UDPOpen() function if (udpSocketUser1 == INVALID_UDP_SOCKET) { serPutByte('B'); serPutByte('a');serPutByte('d'); serPutByte('s');serPutByte('k'); serPutByte('t'); } else { serPutByte('O'); serPutByte('K');serPutByte('-'); serPutByte('s');serPutByte('k'); serPutByte('t'); if (UDPIsPutReady(udpSocketUser1)) { UDPPut('U'); UDPPut('D'); UDPPut('P'); UDPPut(' '); // put data in buffer UDPPut('R'); UDPPut('e'); UDPPut('a'); UDPPut('d'); UDPPut('y'); // put data in buffer UDPFlush(); // send contents and clear } } if (CHECK_ARP_AT_STARTUP) { // open resolving ARP tsec8ARPtimeout = TickGet8bitSec(); // we don't want this ARP thing to go on too long // during startup we can be generaous, though sometimes the watchdog will reboot while(TickGetDiff8bitSec(tsec8ARPtimeout) <= (TICK8)ARP_TIMEOUT_AT_STARTUP) { switch (smUdp1) { case SM_UDP_SEND_ARP: if (ARPIsTxReady()) { //Remember when we sent last request tsecWait = TickGet8bitSec(); //Send ARP request for given IP address ARPResolve(&udpServerNode1.IPAddr); smUdp1 = SM_UDP_WAIT_RESOLVE; serPutByte('\n'); serPutByte('A'); serPutByte('R'); serPutByte('P'); serPutByte('-'); } break; case SM_UDP_WAIT_RESOLVE: //The IP address has been resolved, we now have the MAC address of the //node at 10.1.0.101 if (ARPIsResolved(&udpServerNode1.IPAddr, &udpServerNode1.MACAddr)) { smUdp1 = SM_UDP_RESOLVED; udpSocketUser1 = UDPOpen(DEFAULT_BUS_UDP1PORT, &udpServerNode1, DEFAULT_MOXA_UDPPORT); serPutByte('\n'); serPutByte('r'); serPutByte('e'); serPutByte('s'); serPutByte('v'); serPutByte('d'); } //If not resolved after 2 seconds, send next request else { if (TickGetDiff8bitSec(tsecWait) >= (TICK8)2) { smUdp1 = SM_UDP_SEND_ARP; serPutByte('\n'); serPutByte('w'); serPutByte('a'); serPutByte('i'); serPutByte('t'); } } break; case SM_UDP_RESOLVED: //Checks if there is a transmit buffer ready for accepting data if (UDPIsPutReady(udpSocketUser1)) { //Send a UDP Datagram with "Hello" UDPPut('H'); UDPPut('e'); UDPPut('l'); UDPPut('l'); UDPPut('o'); //Send contents of transmit buffer, and free buffer UDPFlush(); smUdp1 = SM_UDP_SENT; //Set to "message sent" state } break; case SM_UDP_SENT: //Message sent state. If the user wants to resend the message, smUdp1 must be reset //to SM_UDP_RESOLVED break; } //This task performs normal stack task including checking for incoming //packet, type of packet and calling appropriate stack entity to //process it. StackTask(); } if (smUdp1 != SM_UDP_RESOLVED) { serPutByte('\n'); serPutByte('A'); serPutByte('R'); serPutByte('P'); serPutByte('n'); serPutByte('o'); } } else { // need to give acceleraometer time to start up tsec8ARPtimeout = TickGet8bitSec(); while(TickGetDiff8bitSec(tsec8ARPtimeout) <= (TICK8)ARP_TIMEOUT_AT_STARTUP) { // do nothing. } } #endif // end USGS initializations /* * Once all items are initialized, go into infinite loop and let * stack items execute their tasks. * If application needs to perform its own task, it should be * done at the end of while loop. * Note that this is a "co-operative mult-tasking" mechanism * where every task performs its tasks (whether all in one shot * or part of it) and returns so that other tasks can do their * job. * If a task needs very long time to do its job, it must broken * down into smaller pieces so that other tasks can have CPU time. */ while(1) { aliveCntrMain = 38; //Reset if not services in 52.42ms x 38 = 2 seconds //Blink SYSTEM LED every second. if (appcfgGetc(APPCFG_SYSFLAGS) & APPCFG_SYSFLAGS_BLINKB6) { //Configure RB6 as output, and blink it every 500ms if ( TickGetDiff8bit(t) >= ((TICK8)TICKS_PER_SECOND / (TICK8)2) ) { t = TickGet8bit(); //If B6 is configured as input, change to output if (appcfgGetc(APPCFG_TRISB) & 0x40) { appcfgPutc(APPCFG_TRISB, appcfgGetc(APPCFG_TRISB) & 0b10111111); } TRISB_RB6 = 0; LATB6 ^= 1; //Toggle //Toggle IOR5E LED, if IOR5E is present if (appcfgGetc(APPCFG_XBRD_TYPE) == XBRD_TYPE_IOR5E) { ior5eLatchData.bits.ledPWR ^= 1; // Toggle } } } //This task performs normal stack task including checking for incoming packet, //type of packet and calling appropriate stack entity to process it. StackTask(); //Service LCD display lcdService(); //Process commands cmdTask(); //Process events evtTask(); //Process serial busses busTask(); //I2C Task i2cTask(); #if defined(STACK_USE_HTTP_SERVER) //This is a TCP application. It listens to TCP port 80 //with one or more sockets and responds to remote requests. HTTPServer(); #endif #if defined(STACK_USE_FTP_SERVER) FTPServer(); #endif #if defined(STACK_USE_ANNOUNCE) DiscoveryTask(); #endif #if defined(STACK_USE_NBNS) NBNSTask(); #endif //Add your application speicifc tasks here. ProcessIO(); //For DHCP information, display how many times we have renewed the IP //configuration since last reset. if ( DHCPBindCount != myDHCPBindCount ) { #if (DEBUG_MAIN >= LOG_INFO) debugPutMsg(2); //@mxd:2:DHCP Bind Count = %D debugPutByteHex(DHCPBindCount); #endif //Display new IP address #if (DEBUG_MAIN >= LOG_INFO) debugPutMsg(3); //@mxd:3:DHCP complete, IP = %D.%D.%D.%D debugPutByteHex(AppConfig.MyIPAddr.v[0]); debugPutByteHex(AppConfig.MyIPAddr.v[1]); debugPutByteHex(AppConfig.MyIPAddr.v[2]); debugPutByteHex(AppConfig.MyIPAddr.v[3]); #endif myDHCPBindCount = DHCPBindCount; #if defined(STACK_USE_ANNOUNCE) AnnounceIP(); #endif } // USGS - re-check ARP //if (!(smUdp0 == SM_UDP_RESOLVED)) tsecWaitARPrecheck = TickGet16bit(); // from example tick, execute every second with 16 bit tick, have up to 65536 sec or 18.2 hours // we want to check every 1 min... if (RE_CHECK_ARP & ( TickGetDiffSec(tsec16ARPrecheck) >= (TICK16)60 ) ) { tsec16ARPrecheck = TickGetSec(); //count += 1; //itoa((unsigned int)count, buf); serPutByte('\n'); serPutByte('A'); serPutByte('R'); serPutByte('P'); serPutByte('0'); //serPutString((BYTE*)buf); if (smUdp0 != SM_UDP_RESOLVED) { // open resolving ARP smUdp0 = SM_UDP_SEND_ARP; tsec8ARPtimeout = TickGet8bitSec(); // this needs to be short ot the watchdog will reboot! while(TickGetDiff8bitSec(tsec8ARPtimeout) <= (TICK8)1) { switch (smUdp0) { case SM_UDP_SEND_ARP: if (ARPIsTxReady()) { //Remember when we sent last request tsecWait = TickGet8bit(); // this timeout is now < 1 Sec //Send ARP request for given IP address ARPResolve(&udpServerNode0.IPAddr); smUdp0 = SM_UDP_WAIT_RESOLVE; serPutByte('\n'); serPutByte('A'); serPutByte('R'); serPutByte('P'); serPutByte('-'); } break; case SM_UDP_WAIT_RESOLVE: //The IP address has been resolved, we now have the MAC address of the //node at 10.1.0.101 if (ARPIsResolved(&udpServerNode0.IPAddr, &udpServerNode0.MACAddr)) { smUdp0 = SM_UDP_RESOLVED; udpSocketUser0 = UDPOpen(DEFAULT_BUS_UDP1PORT, &udpServerNode0, DEFAULT_MOXA_UDPPORT); serPutByte('\n'); serPutByte('r'); serPutByte('e'); serPutByte('s'); serPutByte('v'); serPutByte('d'); } //If not resolved after 10 ms, abort else { if (TickGetDiff8bit(tsecWait) >= ((TICK8)TICKS_PER_SECOND / (TICK16)2)) { smUdp0 = SM_UDP_SEND_ARP; serPutByte('\n'); serPutByte('w'); serPutByte('a'); serPutByte('i'); serPutByte('t'); } } break; case SM_UDP_RESOLVED: //Checks if there is a transmit buffer ready for accepting data if (UDPIsPutReady(udpSocketUser0)) { //Send a UDP Datagram with "Hello" UDPPut('H'); UDPPut('e'); UDPPut('l'); UDPPut('l'); UDPPut('o'); //Send contents of transmit buffer, and free buffer UDPFlush(); smUdp0 = SM_UDP_SENT; //Set to "message sent" state } break; case SM_UDP_SENT: //Message sent state. If the user wants to resend the message, smUdp0 must be reset //to SM_UDP_RESOLVED break; } //This task performs normal stack task including checking for incoming //packet, type of packet and calling appropriate stack entity to //process it. StackTask(); } if (!(smUdp0 == SM_UDP_RESOLVED)) { serPutByte('\n'); serPutByte('A'); serPutByte('R'); serPutByte('P'); serPutByte('n'); serPutByte('o'); } } } // end USGS } // end of while } static void ProcessIO(void) { static TICK8 tmr10ms = 0; static TICK16 tms100ms = 0; // 16 bit tick counter BYTE c, b1, b2, b3; unsigned int crc; BYTE nbytes; BYTE nreceived = 0; BYTE ArmSenseValueH; // high bits BYTE ArmSenseValueL; // low bits BYTE ArmTripFlag = 0; BYTE IsTripArmed = 0; BYTE PortFValue = 0; // we want to confirm a UDP order //Enter each 10ms // TICKS_PER_SECOND = 100ul = 10ms //if ( TickGetDiff8bit(tmr10ms) >= ((TICK8)TICKS_PER_SECOND / (TICK8)100) ) // original code if ( TickGetDiff8bit(tmr10ms) >= (10*((TICK8)TICKS_PER_SECOND / (TICK8)100)) ) { tmr10ms = TickGet8bit(); /* USGS // remove this - no expansion board //Service Expansion Board, if any is present switch(appcfgGetc(APPCFG_XBRD_TYPE)) { case XBRD_TYPE_MXD2R: mxd2rService(); break; case XBRD_TYPE_IOR5E: ior5eService(); break; } */ // now to collect an intact IG-20 data frame #if IG20_ON_SER1 if (serIsGetReady()) { // read only one, because we will go off and do other things b1 = serGetByte(); // is this the first byte of an IG-20 data frame? if (b1 == 0xff) { //maybe - if this is really the sync byte b2 = serGetByte(); if (b2 == 0x02) { // this is the tx byte b3 = serGetByte(); // the command byte 0x90 if (b3 == 0x90) { // this is the tx byte // get char by char, this is most successful so far bufSer2UDP[bytesInSer2UDP++] = b1; //ff bufSer2UDP[bytesInSer2UDP++] = b2; //02 bufSer2UDP[bytesInSer2UDP++] = b3; //90 b1 = serGetByte(); // the data length, MSB byte b2 = serGetByte(); // the data length, LSB byte bufSer2UDP[bytesInSer2UDP++] = b1; // save them bufSer2UDP[bytesInSer2UDP++] = b2; // this usually works without dropping data // need time for interrupts to do their work nbytes = IG20_FRAME_LENGTH-2; nreceived = USARTGetIG20((char *)bufSer2UDP+sizeof(char)*5, nbytes); busEmptyRxBuf(BUSID_SER1); // clear that received data // check the CRC crc = calcCRC(bufSer2UDP+sizeof(BYTE)*2, IG20_FRAME_LENGTH-5); bytesInSer2UDP += nreceived-4; // indicate if the trip circuit is armed, Trip C5 and Reset B2 are zero // note that bringing B2 high resets the trip and makes C5 low. // B5 needs to be brought back down low to arm the trip (i.e. B5 is a toggle) if (!PORTB_RB2 && !PORTC_RC5) { bufSer2UDP[bytesInSer2UDP++] = 1; // armed } else { bufSer2UDP[bytesInSer2UDP++] = 0; // not armed } bufSer2UDP[bytesInSer2UDP++] = (BYTE)((crc>>8) & 0x00ff); // MSB bufSer2UDP[bytesInSer2UDP++] = (BYTE)(crc & 0x00ff); // LSB } } } // important to empty this buffer at this point - or it will miss IG 20 data frames busEmptyRxBuf(BUSID_SER1); // clear that received data } #endif #if IG20_ON_SER2 if (ser2IsGetReady()) { // read only one, because we will go off and do other things b1 = ser2GetByte(); // is this the first byte of an IG-20 data frame? if (b1 == 0xff) { //maybe - if this is really the sync byte b2 = ser2GetByte(); if (b2 == 0x02) { // this is the tx byte b3 = ser2GetByte(); // the command byte 0x90 if (b3 == 0x90) { // this is the tx byte // get char by char, this is most successful so far bufSer2UDP[bytesInSer2UDP++] = b1; //ff bufSer2UDP[bytesInSer2UDP++] = b2; //02 bufSer2UDP[bytesInSer2UDP++] = b3; //90 b1 = ser2GetByte(); // the data length, MSB byte b2 = ser2GetByte(); // the data length, LSB byte bufSer2UDP[bytesInSer2UDP++] = b1; // save them bufSer2UDP[bytesInSer2UDP++] = b2; // this usually works without dropping data // need time for interrupts to do their work nbytes = IG20_FRAME_LENGTH-2; nreceived = USART2GetIG20((char *)bufSer2UDP+sizeof(char)*5, nbytes); // check the CRC crc = calcCRC(bufSer2UDP+sizeof(BYTE)*2, IG20_FRAME_LENGTH-5); bytesInSer2UDP += nreceived-4; // indicate if the trip circuit is armed, Trip C5 and Reset B2 are zero // note that bringing B2 high resets the trip and makes C5 low. // B5 needs to be brought back down low to arm the trip (i.e. B5 is a toggle) if (!PORTB_RB2 && !PORTC_RC5) { bufSer2UDP[bytesInSer2UDP++] = 1; // armed } else { bufSer2UDP[bytesInSer2UDP++] = 0; // not armed } bufSer2UDP[bytesInSer2UDP++] = (BYTE)((crc>>8) & 0x00ff); // MSB bufSer2UDP[bytesInSer2UDP++] = (BYTE)(crc & 0x00ff); // LSB } } } // important to empty this buffer at this point - or it will miss IG 20 data frames busEmptyRxBuf(BUSID_SER2); // clear that received data } #endif else { #if FAKE_IG20 // LEN Q1 Q4 Roll Pitch Yaw Ax Ay Az T1 T2 CRC ETX // ff 02 90 0034 3f7ffff0 3a534000 398b8000 00000000 3ad2e000 3a0b0000 00000000 3bab8800 bc81a200 c11ce3d9 421d1070 419c4000 000f5ac8 a473 03 41 a473 000001 bufSer2UDP[bytesInSer2UDP++] = 0xff; bufSer2UDP[bytesInSer2UDP++] = 0x02; bufSer2UDP[bytesInSer2UDP++] = 0x90; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x34); // SYNCX STX CMD LEN 0x00, LEN 0x01 bufSer2UDP[bytesInSer2UDP++] = 0x3f; bufSer2UDP[bytesInSer2UDP++] = 0x7f; bufSer2UDP[bytesInSer2UDP++] = 0xff; bufSer2UDP[bytesInSer2UDP++] = 0xf0; // SBG_OUTPUT_TIME_SINCE_RESET in milliseconds, as unit32, 4 bytes total // SBG_OUTPUT_QUATERNION q0, q1, q2, q3, real32 (4 bytes each), 16 bytes total bufSer2UDP[bytesInSer2UDP++] = 0x3a; bufSer2UDP[bytesInSer2UDP++] = 0x53; bufSer2UDP[bytesInSer2UDP++] = 0x40; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x39; bufSer2UDP[bytesInSer2UDP++] = 0x8b; bufSer2UDP[bytesInSer2UDP++] = 0x80; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x3a; bufSer2UDP[bytesInSer2UDP++] = 0xd2; bufSer2UDP[bytesInSer2UDP++] = 0xe0; bufSer2UDP[bytesInSer2UDP++] = 0x00; // SBG_OUTPUT_EULER Roll, Pitch, Yaw, real32 (4 bytes each), 12 bytes total bufSer2UDP[bytesInSer2UDP++] = 0x3a; bufSer2UDP[bytesInSer2UDP++] = 0x0b; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x3b; bufSer2UDP[bytesInSer2UDP++] = 0xab; bufSer2UDP[bytesInSer2UDP++] = 0x88; bufSer2UDP[bytesInSer2UDP++] = 0x00; // SBG_OUTPUT_ACCELEROMETERS Ax, Ay, Az, real32 (4 bytes each), 12 bytes total bufSer2UDP[bytesInSer2UDP++] = 0xbc; bufSer2UDP[bytesInSer2UDP++] = 0x81; bufSer2UDP[bytesInSer2UDP++] = 0xa2; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0xc1; bufSer2UDP[bytesInSer2UDP++] = 0x1c; bufSer2UDP[bytesInSer2UDP++] = 0xe3; bufSer2UDP[bytesInSer2UDP++] = 0xd9; bufSer2UDP[bytesInSer2UDP++] = 0x42; bufSer2UDP[bytesInSer2UDP++] = 0x1d; bufSer2UDP[bytesInSer2UDP++] = 0x10; bufSer2UDP[bytesInSer2UDP++] = 0x70; // SBG_OUTPUT_TEMPERATURES T0, T1, real32 (4 bytes each), 8 bytes total bufSer2UDP[bytesInSer2UDP++] = 0x41; bufSer2UDP[bytesInSer2UDP++] = 0x9c; bufSer2UDP[bytesInSer2UDP++] = 0x40; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x00; bufSer2UDP[bytesInSer2UDP++] = 0x0f; bufSer2UDP[bytesInSer2UDP++] = 0x5a; bufSer2UDP[bytesInSer2UDP++] = 0xc8; bufSer2UDP[bytesInSer2UDP++] = 0xa4; bufSer2UDP[bytesInSer2UDP++] = 0x73; // CRC bufSer2UDP[bytesInSer2UDP++] = 0x03; // ETX #endif #if !FAKE_IG20 for (b1=0; b1>8) & 0x00ff); bufSer2UDP[bytesInSer2UDP++] = ArmSenseValueH; // put data in buffer bufSer2UDP[bytesInSer2UDP++] = ArmSenseValueL; // put data in buffer ArmSenseValueL = (BYTE) (AdcValues[1] & 0x00ff); ArmSenseValueH = (BYTE) ((AdcValues[1]>>8) & 0x00ff); bufSer2UDP[bytesInSer2UDP++] = ArmSenseValueH; // put data in buffer bufSer2UDP[bytesInSer2UDP++] = ArmSenseValueL; // put data in buffer // this port is configured as an output, can't use PORT, must use LAT (Latch) PortFValue = (BYTE)(LATF); bufSer2UDP[bytesInSer2UDP++] = PortFValue; // put data in buffer ArmTripFlag = PORTC_RC5; bufSer2UDP[bytesInSer2UDP++] = ArmTripFlag; // put data in buffer ArmSenseValueH = 0; ArmSenseValueL = 0; StackTask(); // let's take care of business here, as often the UDP port won't be ready so soon if (UDPIsPutReady(udpSocketUser0)) { UDPPutArray((BYTE *)bufSer2UDP,(WORD)(bytesInSer2UDP)); // this means there will be a UDP message every 10 ms which may or may not have IG20 data frame UDPFlush(); // send contents and clear serPutByte('0'); //serPutByte(PortFValue); } #ifdef DO2SOCKETS StackTask(); // let's take care of business here, as often the UDP port won't be ready so soon if (UDPIsPutReady(udpSocketUser1)) { UDPPutArray((BYTE *)bufSer2UDP,(WORD)(bytesInSer2UDP)); // this means there will be a UDP message every 10 ms which may or may not have IG20 data frame UDPFlush(); // send contents and clear serPutByte('1'); } #endif b1=0; b2=0; bytesInSer2UDP = 0; nreceived = 0; // diagnostic to measure serial output, get 1 bit at 116.3 kHz // serPutByte(0xaa); } // end USGS //Convert next ADC channel, and store result in adcChannel array #if (defined(APP_USE_ADC8) || defined(APP_USE_ADC10)) && (ADC_CHANNELS > 0) { static BYTE adcChannel; //Current ADC channel. Value from 0 - n static BOOL ADC_Wait = 0; //Increment ADCChannel and start new convertion if (!ADC_Wait) { //Increment to next ADC channel if ((++adcChannel) >= ADC_CHANNELS) { adcChannel = 0; } //Check if current ADC channel (adcChannel) is configured to be ADC channel if (adcChannel < ((~ADCON1) & 0x0F)) { //Convert next ADC Channel ADCON0 &= ~0x3C; ADCON0 |= (adcChannel << 2); ADCON0_ADON = 1; //Switch on ADC ADCON0_GO = 1; //Go ADC_Wait = 1; } //Not ADC channel, set to 0 else { AdcValues[adcChannel] = 0; } } //End of ADC Convertion: save data if ((ADC_Wait)&&(!ADCON0_GO)) { #if defined(APP_USE_ADC8) AdcValues[adcChannel] = ADRESH; #elif defined(APP_USE_ADC10) //AdcValues[adcChannel] = (WORD) ((((WORD)ADRESH) << 8) | ((WORD)ADRESL)); //AdcValues[adcChannel] = (WORD)((ADRESH*256)+ADRESL); AdcValues[adcChannel] = ((WORD)ADRESH << 8) | (WORD)ADRESL; #endif ADC_Wait = 0; } } #endif // end of ADC conversion } // function ProcessIO static ROM char HTTPHDR_AUTHORIZATION[] = "AUTHORIZATION: BASIC "; /** * This function is a "callback" from HTTPServer task. For each HTTP Header found in the HTTP Request * message from the client, this function is called. The application has the chance to parse the * received headers. * * @param httpInfo HTTP_INFO structure of current HTTP connection * @param hdr Buffer containing NULL terminated header to handle * @param rqstRes Name of the Requested resource - GET command's action. All characters are in uppercase! */ void HTTPProcessHdr(HTTP_INFO* httpInfo, BYTE* hdr, BYTE* rqstRes) { BYTE i; char unpw[20]; //Buffer for storing username and password, seperated by ':' char base64[25]; //Buffer for storing base64 result //Check if buffer begins with ROM string, ignore case if (strBeginsWithIC((char*)hdr, HTTPHDR_AUTHORIZATION)) { i = strcpyee2ram(unpw, APPCFG_USERNAME0, 8); //Returns number of bytes written, excluding terminating null unpw[i++] = ':'; //Overwrite terminating null with ':' strcpyee2ram(&unpw[i], APPCFG_PASSWORD0, 8); base64Encode((char*)base64, (char*)unpw, strlen(unpw)); if (strcmp( (char*)(&hdr[sizeof(HTTPHDR_AUTHORIZATION)-1]), base64) == 0) { httpInfo->flags.bits.bUserLoggedIn = TRUE; #if (DEBUG_MAIN >= LOG_DEBUG) debugPutMsg(6); //@mxd:6:HTTP User Authenticated #endif } } } ///////////////////////////////////////////////// //Implement callback for FTPVerify() function #if defined(STACK_USE_FTP_SERVER) #if (FTP_USER_NAME_LEN > APPCFG_USERNAME_LEN) #error "The FTP Username length can not be shorter then the APPCFG Username length!" #endif BOOL FTPVerify(char *login, char *password) { #if (DEBUG_MAIN >= LOG_INFO) debugPutMsg(4); //@mxd:4:Received FTP Login (%s) and Password (%s) debugPutString(login); debugPutString(password); #endif if (strcmpee2ram(login, APPCFG_USERNAME0) == 0) { if (strcmpee2ram(password, APPCFG_PASSWORD0) == 0) { return TRUE; } } return FALSE; } #endif /** * Initialize the boards hardware */ static void InitializeBoard(void) { #if (defined(MCHP_C18) && (defined(__18F458) || defined(__18F448) || defined(__18F6680))) \ || (defined(HITECH_C18) && (defined(_18F458) || defined(_18F448) || defined(_18F6680))) CMCON = 0x07; /* Comparators off CM2:CM0 = 111 for PIC 18F448, 18F458, 18F6680 */ #endif ///////////////////////////////////////////////// //Enable 4 x PLL if configuration bits are set to do so #if ( defined(MCHP_C18) && defined(__18F6621)) OSCCON = 0x04; //Enable PLL (PLLEN = 1) while (OSCCON_LOCK == 0); //Wait until PLL is stable (LOCK = 1) //Seeing that this code does currently not work with Hi-Tech compiler, disable this feature OSCCON_SCS1 = 1; //Switch on software 4 x PLL if flag is set in configuration data //if (appcfgGetc(APPCFG_SYSFLAGS) & APPCFG_SYSFLAGS_PLLON) { // OSCCON_SCS1 = 1; //} #endif ///////////////////////////////////////////////// //Setup timer1 as a free running 16 bit timer. //TMR1L is incremented every 800ns. TMR1H is incremented every 204.8us //Is used to measure events in code. //TMR1H.bit0 is toggled every 204.8us //TMR1H.bit1 is toggled every 409.6us //TMR1H.bit2 is toggled every 819.2us //TMR1H.bit3 is toggled every 1.6384ms //TMR1H.bit4 is toggled every 3.2768ms //TMR1H.bit5 is toggled every 6.5536ms //TMR1H.bit6 is toggled every 13.1072ms //TMR1H.bit7 is toggled every 26.2144ms //1xxx xxxx = Enable read/write as a 16bit times. TMR1H is a buffer that is loaded when TMR1L is accessed. //xx11 xxxx = No prescaler //xxxx 0xxx = Timer1 oscillator disabled (RC0 and RC1) //xxxx xx0x = Internal clock source = Fosc/4 = 40/4 = 10MHz for a 40MHz clock //xxxx xxx1 = Timer 1 on T1CON = 0xB1; T1CON_RD16 = 0; //Enable reading TMR1L and TMR1H individually //When reading TMR1 in code, execute following command if TMR1L and TMR1H byte has to be read as a single value //T1CON_RD16 = 1; //Enable reading TMR1L and TMR1H as 16-bit value //If TMR1H has to be read on it's own (without first reading TMR1L), execute following command. //T1CON_RD16 = 0; //Enable reading TMR1L and TMR1H individually //Disable external pull-ups INTCON2_RBPU = 1; // 1 = disable // USGS these pullups need to be disabled for the controller board to work //Enable T0 interrupt T0CON = 0; // USGS set baud rate here to match IG20, APPCFG_USART1_BAUD = IG20_BAUD as defined in projdefs.h if (!(appcfgGetc(APPCFG_USART1_CFG) & APPCFG_USART_ENABLE)) { // check to see if we already have the baud we want appcfgPutc(APPCFG_USART1_CFG, APPCFG_USART_ENABLE); } if (!(appcfgGetc(APPCFG_USART1_BAUD) == IG20_BAUD)) { // check to see if we already have the baud we want appcfgPutc(APPCFG_USART1_BAUD, IG20_BAUD); } // enable USART2 if (!(appcfgGetc(APPCFG_USART2_CFG) & APPCFG_USART_ENABLE)) { // check to see if we already have the baud we want appcfgPutc(APPCFG_USART2_CFG, APPCFG_USART_ENABLE); } if (!(appcfgGetc(APPCFG_USART2_BAUD) == IG20_BAUD)) { // check to see if we already have the baud we want appcfgPutc(APPCFG_USART2_BAUD, IG20_BAUD); } // end USGS // Note that these port configuration settings must be here, before appcfgCpuIO, to make a permanent change // port F is the control output to the Technadyne // this was helpful http://en.wikipedia.org/wiki/Mask_%28computing%29 if (appcfgGetc(APPCFG_TRISF) | 0b00000000) { // check to see if any are inputs (any bit is 1) appcfgPutc(APPCFG_TRISF, 0b00000000); // port F to our resistor tree needs to be all outputs } //if (appcfgGetc(APPCFG_PORTF) | 0b00000000) { // the values need to be all zeros // appcfgPutc(APPCFG_PORTF, 0b00000000); //} // the values need to be 127 = 0x7F = 0b01111111 if (!(appcfgGetc(APPCFG_PORTF) & 0b01111111)) { appcfgPutc(APPCFG_PORTF, 0b01111111); // for dead band, all stop on power up } // we need to make sure we have A0 and A1 set as input for A/D use if (!(appcfgGetc(APPCFG_TRISA) & 0b00000011)) { // check if A0 & A1 is an input (bits 0 and 1 are = 1) appcfgPutc(APPCFG_TRISA, (appcfgGetc(APPCFG_TRISA) & 0b11111100) | 0b00000011); // port A pins 0 and 1, our current sense & tach, need to be inputs (1) } // Port B has Technadyne control functions on bits 0-3 // B0 is the tripped indicator, we want to start not tripped // switch to pin C5 //PORTC_RC5 = 0 //if (!((appcfgGetc(APPCFG_TRISB) & 0b00000001) & 0b00000001)) { // check to see if B0 is an input (1) // appcfgPutc(APPCFG_TRISB, (appcfgGetc(APPCFG_TRISB) & 0b11111110) | 0b00000001 ); // set B0 an input (1) //} if (!((appcfgGetc(APPCFG_TRISC) & 0b00100000) & 0b00100000)) { // check to see if C5 is an input (1) appcfgPutc(APPCFG_TRISC, (appcfgGetc(APPCFG_TRISC) & 0b11011111) | 0b00100000 ); // set C5 an input (1) } PORTC_RC5 = 0; // this doesn't work - starts with pullup, hmm //PORTB_RB1 = 0; // unclamp (1=allow control voltage out) i.e. the parking brake if ((appcfgGetc(APPCFG_TRISB) & 0b00000010) | 0b00000000) { // check to see if B1 is an output (0) appcfgPutc(APPCFG_TRISB, (appcfgGetc(APPCFG_TRISB) & 0b11111101) & 0b11111101 ); // set B1 an output (0) } PORTB_RB1 = 0; // unclamp //PORTB_RB2 = 0; // reset (1 = apply reset); if ((appcfgGetc(APPCFG_TRISB) & 0b00000100) | 0b00000000) { // check to see if B2 is an output (0) appcfgPutc(APPCFG_TRISB, (appcfgGetc(APPCFG_TRISB) & 0b11111011) & 0b11111011 ); // set B2 an output (0) } PORTB_RB2 = 0; // we are not resetting... wake up with motor off //PORTB_RB3 = 1; // 1 = allow power to technadyne instrumentation if ((appcfgGetc(APPCFG_TRISB) & 0b00001000) | 0b00000000) { // check to see if B3 is an output (0) appcfgPutc(APPCFG_TRISB, (appcfgGetc(APPCFG_TRISB) & 0b11110111) & 0b11110111 ); // set B3 an output (0) } PORTB_RB3 = 1; // DO NOT SEND instrumentation power to motor immediately // C0 is output for +12v on to the accelerometer if ((appcfgGetc(APPCFG_TRISC) & 0b00000001) | 0b00000000) { // check to see if C0 is an output (0) appcfgPutc(APPCFG_TRISC, (appcfgGetc(APPCFG_TRISC) & 0b11111110) & 0b11111110 ); // set C0 an output (0) } //PORTB_RC0 = 0; // 0 = keep accelerometer off until after the RS232 menu is done. PORTC_RC0 = 0; // need to configure the A/D // end USGS } // USGS crc calc for IG20 from IG20 docs // try this cast as BYTE // checked this by outputting the calculated CRC on UDP and it matched the crc in the IG20 packet unsigned int calcCRC(BYTE *pBuffer, unsigned int bufferSize) { unsigned int poly = 0x8408; // 16 bit int unsigned int crc = 0; unsigned char carry; // 8 bit unsigned char i_bits; unsigned int j; for (j=0; j