#include #define QTOP 599 #define QBOT 0 #define QLEN 600 char rfc[QLEN]; int rfpop, rfpush, rffull; #include "delay.h" long ms, msec; char cbit, cval,coutflag; long cms; void putch(unsigned char c) { while(!TRMT) /* TRMT1 is set when TSR is empty */ continue; TXREG = c; /* load the register */ } void interrupt HI_ISR(void) { if (CCP1IF==1) { ms += 10; CCP1IF = 0; } if (INT0IF==1) { // Interrupt from RB0 falling edge [barcode clock] if (cbit==0) { if (RB1==1) { cms = ms+msec; cbit++; } } else { cbit++; cval = cval<<1 | RB1; if (cbit>8) { // only output if less than 20cm@0.5m/s=400ms has elapsed if (((ms+msec)-cms)<400) coutflag = 1; cbit = 0; // reset bit counter in any case } } INT0IF = 0; } } void DelayMs(unsigned char cnt) { unsigned char i; while (cnt--) { i=4; while(i--) { DelayUs(uS_CNT); /* Adjust for error */ } ; } ; } void spi_write(unsigned char c) { SSPBUF = c; while (BF==0); /* still shifting this out */ } unsigned char spi_read(unsigned char c) { unsigned char rc; SSPBUF = c; while (BF==0); rc = SSPBUF; return rc; } void que_in(char qdata) { if (rfpush == QTOP) rfpush = QBOT; else rfpush++; rfc[rfpush] = qdata; rffull = 1; } char que_out() { char ch; if (rfpop == QTOP) rfpop = QBOT; else rfpop++; if (rfpush == rfpop) rffull = 0; ch = rfc[rfpop]; return ch; } void witsend(char ich, char nb, char *buf) { /* abbreviated version not in aster format yet */ int i; long mst; mst = ms + msec; // que_in(0x02); /* WIT mode 4 */ // que_in(0x00); /* WIT handle: 0=remote to base */ // que_in(nb+7); /* WIT message length */ que_in(*(((char *)(&mst))+3)); //ASTER timetag que_in(*(((char *)(&mst))+2)); que_in(*(((char *)(&mst))+1)); que_in(*(char *)(&mst)); que_in(ich); // ASTER channel que_in(nb); // ASTER data length for (i=0; i>4; RA2 = 1; RA2 = 0; //bit4 RA3 = (com & 0x08)>>3; RA2 = 1; RA2 = 0; //bit5 RA3 = (com & 0x04)>>2; RA2 = 1; RA2 = 0; //bit6 RA3 = (com & 0x02)>>1; RA2 = 1; RA2 = 0; //bit7 RA3 = (com & 0x01); RA2 = 1; //bit 8 TRISA = TRISA | 0x08; // set DATA to input RA2 = 0; //end of bit8 RA2 = 1; c = RA3; RA2 = 0; // read DATA if (c == 0) { //normal TRISA = TRISA & 0xF3; // set data high while waiting RA3 = 1; TRISA = TRISA | 0x08; // back to input return 0; } else { //bad return 1; } } int shtread(void) { // assume DATA is input on entry int i; unsigned int iv; unsigned char c; TRISA = TRISA | 0x08; iv = 0; RA2 = 0; for (i=0; i<8; i++) { // first 8 bits RA2 = 1; c = RA3; RA2 = 0; // read bit iv = (iv<<1) | c; // append to iv } TRISA = TRISA & 0xF7; // set DATA to output RA3 = 0; RA2 = 1; RA2 = 0; // acknow. bit TRISA = TRISA | 0x08; // set DATA to input for (i=0; i<8; i++) { // next 8 bits RA2 = 1; c = RA3; RA2 = 0; // read bit iv = (iv<<1) | c; // append to iv } TRISA = TRISA & 0xF7; // set DATA to output RA3 = 1; // set data high RA2 = 1; RA2 = 0; // no clk says don't worry about checksum [for now] TRISA = TRISA | 0x08; // set DATA to input if ( (iv & 0xC000)!=0) iv = 0xFFFF; // make sure first 2 bits ==0 return iv; } void main(void) { int i,iv,jv,isec; char ival[2], c; char pmasks[4] = {0x04, 0x08, 0x10, 0x20}; char gib, cib, sib, hib; char gbuf[80], cbuf[60], sbuf[40], hbuf[20]; char first, rhflag; char hh,mm,ss; /* initialize misc */ di(); __CONFIG(1,ECRA6); __CONFIG(2,WDTEN & PWRTEN); __CONFIG(4,LVPDIS); SWDTEN = 0; first = 5; ms = 0; msec = 0; isec = 0; coutflag = 0; cval = 0; cbit = 0; /* initialize UART: 115Kb at 20MHz clock */ SPBRG=10; TXSTA=0x26; SPEN=1; CREN = 1; /* disable A/D */ ADCON0 = 0x00; /* turn off A/D (RA0-3) */ ADCON1 = 0x07; /* set all PORTA to digital */ /* initialize SPI */ TRISC = 0x97; /* use both SPI and UART */ SSPCON1 = 0x21; /* SPI: enabled, idle low, master /16 */ SSPSTAT = 0x40; /* SPI: middle rising edge */ /* initialize max3111s */ TRISB = 0xC3; /* RB2-5 are outputs */ RBPU = 1; /* disable port B pull-ups (only for inputs) */ PORTB = 0xFF; /* set RB2-5 high (not selecting max's) */ maxinit(pmasks[3], 0x0A); /* HMR: 19200, 8N1 */ maxinit(pmasks[2], 0x0A); /* GPS: 19200, 8N1 */ maxinit(pmasks[1], 0x0B); /* CO2: 9600, 8N1 */ maxinit(pmasks[0], 0x0B); /* Sonic: 9600, 8N1 */ /* initialize RMT */ /* ... send "go" to RMT CO2 after waiting a bit to stabilize */ DelayMs(200); ival[0]='\r'; maxsend(pmasks[1],ival); CLRWDT(); DelayMs(2); ival[0]='g'; maxsend(pmasks[1],ival); DelayMs(2); ival[0]='o'; maxsend(pmasks[1],ival); DelayMs(2); ival[0]='\r'; maxsend(pmasks[1],ival); /* initialize GPS -- send "0x1E" to force cold start */ /* (do I also need 0x25 for reset?) */ /* Can take up to 15 min to reacquire! */ ival[0]=0x1E; maxsend(pmasks[2],ival); /* reset SHT */ shtcom(0xFF); /* set up interrupts */ RCON = 0x80; // Use interrupt priority INTCON = 0xD0; // Enable unmasked interrupts and INT0 (RB0) change interrupt INTCON2 = 0x01; // PortB int is high priority -- falling edge /* set up timer (used for ms timing) */ T1CON = 0x35; // TIMER 1 on, 2-8bit, FOSC/4/8 CCP1CON = 0x0B; // Compare mode, special event clears Timer1 CCPR1H = 0x18; // Period is 6250 => 10ms CCPR1L = 0x6A; CCP1IP = 1; // CCP interrupt is high priority CCP1IE = 1; // CCP interrupts enabled! TMR1L = 0; // clear timer 1 TMR1H = 0; ei(); while(1) { CLRWDT(); //Check for command if (RCIF) { c = RCREG; if (c=='S') RA5 = 0; // Stop -- motor off if (c=='G') RA5 = 1; // Go -- motor on if (c=='C') { // Calibrate HMR DelayMs(50); ival[0] = '*'; maxsend(pmasks[3],ival); DelayMs(50); ival[0] = 'C'; maxsend(pmasks[3],ival); } if (c=='R') { /* send "go" to RMT CO2 [in case it doesn't] */ DelayMs(50); ival[0] = '\r'; maxsend(pmasks[1],ival); DelayMs(50); ival[0] = 'g'; maxsend(pmasks[1],ival); DelayMs(50); ival[0] = 'o'; maxsend(pmasks[1],ival); DelayMs(50); ival[0] = '\r'; maxsend(pmasks[1],ival); } } //CO2 maxread(pmasks[1], ival); while ( (ival[1] & 0x80) !=0) { CLRWDT(); if ((ival[0] != '\r') && (ival[0] != '\n')) { cbuf[cib++] = ival[0]; if (cib>80) cib = 0; } else { if (ival[0] == '\r') { witsend(201, cib, cbuf); cib = 0; } } maxread(pmasks[1], ival); } //Sonic maxread(pmasks[0], ival); while ( (ival[1] & 0x80) !=0) { CLRWDT(); if ((ival[0] != '\r') && (ival[0] != '\n')) { sbuf[sib++] = ival[0]; if (sib>80) sib = 0; } else { if (ival[0] == '\r') { witsend(200, sib, sbuf); sib = 0; } } maxread(pmasks[0], ival); } //HMR maxread(pmasks[3], ival); while ( (ival[1] & 0x80) !=0) { CLRWDT(); if ((ival[0] != '\r') && (ival[0] != '\n')) { hbuf[hib++] = ival[0]; if (hib>80) hib = 0; } else { if (ival[0] == '\r') { witsend(203, hib, hbuf); hib = 0; } } maxread(pmasks[3], ival); } //GPS maxread(pmasks[2], ival); while ( (ival[1] & 0x80) !=0) { CLRWDT(); if ((ival[0] != '\r') && (ival[0] != '\n')) { gbuf[gib++] = ival[0]; if (gib>80) gib = 0; } else { if (ival[0] == '\r') { // parse message for time hh = (gbuf[7]-'0')*10 + (gbuf[8]-'0'); mm = (gbuf[9]-'0')*10 + (gbuf[10]-'0'); ss = (gbuf[11]-'0')*10 + (gbuf[12]-'0'); if ( (hh<24) && (mm<60) && (ss<60) ) { ms = 0; msec = hh; msec = (msec<<6)-(msec<<2); // *60 msec += mm; msec = (msec<<6)-(msec<<2); // *60 msec += ss; msec = (msec<<10)-(msec<<4)-(msec<<3); // *1000 } witsend(202, gib, gbuf); gib = 0; // now is a good time to start SHT // ...if command doesn't work, reset sht if (shtcom(0x03)!=0) shtcom(0x1E); rhflag = 0; } } maxread(pmasks[2], ival); } // SHT TRISA = TRISA & 0x08; // ensure that we're reading RA3 c = PORTA & 0x08; if ( c==0 ) { iv = shtread(); jv = ((iv&0xFF)<<8) | (iv>>8); witsend(101+rhflag, 2, (char *)(&jv)); if (rhflag==0) { if (shtcom(0x05)!=0) shtcom(0x1E); // start RH reading rhflag = 1; } } // Bar Code (outside ISR so output packets are sync'd and to minimize time in ISR) if (coutflag) { jv = ((int)cval)<<8; witsend(100, 2, (char *)(&jv)); cval = 0; // cbit zeroed in ISR coutflag = 0; } // WIT send (can fit max of 6 bytes at 115.2kb within 1 byte at 19.2kb) // i = 0; // while (rffull && (i<5)) { // putch(que_out()); // i++; // } // (just try one byte at a time) if (rffull) putch(que_out()); } }