/* ppilib.c -- Parallel Port Interface Library 10-OCT-2004 BPA */ #include #include #include #include #include #include #include #define DATA 0x378 /* printer port I/O addresses */ #define STAT 0x379 #define CTL 0x37A #define ADCLO 0 /* select different functions */ #define ADCHI 1 #define ADADR 2 #define ADSTRT 3 #define DAC 4 #define SM 5 #define DOUT 6 #define DIN 7 #define ENBIT 8 /* to avoid decoder spikes */ #define ADEOC 128 /* connected to S7 bar of status byte */ #define FALSE 0 #define TRUE 1 void setDAC(int dat) /* input 0 to 255 */ { outp(DATA, dat); /* DAC goes from -5 to 5 for 0 to 255 */ outp(CTL,DAC); outp(CTL, ENBIT+DAC); outp(CTL,DAC); outp(CTL,0); } int setVoltage(double val) /* input from -5000 to 5000 mV */ { static const double m = 10000.0 / 255; int dat; if( (val < -5000.0) || (val > 5000.0) ) return FALSE; dat = (int) (128.0 + val / m); outp(DATA, dat); /* DAC goes from -5 to 5 for 0 to 255 */ outp(CTL,DAC); outp(CTL, ENBIT+DAC); outp(CTL,DAC); outp(CTL,0); return TRUE; } int selectADC(int chan) { if( (chan < 0) || (chan > 7) ) return FALSE; outp(DATA, chan); outp(CTL,ADADR); outp(CTL, ENBIT+ADADR); outp(CTL,ADADR); outp(CTL,0); return TRUE; } int getRawADC(void) /* returns 0 to 255. used internally */ { int lo,hi,dat; outp(CTL,ADSTRT); outp(CTL, ENBIT+ADSTRT); outp(CTL,ADSTRT); while(inp(STAT) & ADEOC) ; /* wait for EOC bar to go LOW */ outp(CTL, ADCLO); outp(CTL, ENBIT+ADCLO); lo = (inp(STAT) >> 3) & 15; outp(CTL, ADCHI); outp(CTL, ENBIT+ADCHI); hi = (inp(STAT) >> 3) & 15; dat = (hi << 4) | lo; return dat; } double zeroTo5000(void) /* returns 0 to 5000 mV */ { static const double m = 5000.0 / 255; return (double) m * getRawADC(); } double minus5000To5000(void) /* returns -5000 to 5000 mV */ { static const double m = 10000.0 / 255; return (double) m * getRawADC() - 5000; } static int smDelay = 300; int setMotorDelay(int k) { if( (k < 200) || (k <0 )) return FALSE; smDelay = k; return TRUE; } void rotateMotor(int nsteps , int dir) { static int pos = 0; static int seq[4] = {12, 6, 3 ,9}; int i; for( i = 0; i < nsteps; ++i) { if(dir) if(pos == 3) pos = 0; else ++pos; else if(pos == 0) pos = 3; else --pos; outp(DATA , seq[pos]); outp(CTL , SM); outp(CTL , SM + ENBIT); outp(CTL , SM); outp(CTL , 0); delay(smDelay); } } int readInputs(void) { int dat; outp(CTL, DIN); outp(CTL, ENBIT + DIN); dat = (inp(STAT) >> 3) & 15; outp(CTL, DIN); return dat; } void writeOutputs(int dat) { outp(DATA, dat); outp(CTL,DOUT); outp(CTL, ENBIT+ DOUT); outp(CTL,DOUT); } void writeStepper(int dat) { outp(DATA, dat); outp(CTL,SM); outp(CTL, ENBIT+ SM); outp(CTL,SM); } /*--------------------- Timer Routines --------------------------*/ #define TimerResolution 1193181.667 int far* p = (int*) 0x40006cL; static union { int i[2]; long l; } strt, stop; int hob , lob; void markStart(void) { disable(); outp(0x43,0); lob = inp(0x40); hob = inp(0x40); enable(); strt.i[0] = ~((hob << 8) | lob); strt.i[1] = *p; } double elapsedTime(void) { double result; long l; disable(); outp(0x43,0); lob = inp(0x40); hob = inp(0x40); enable(); stop.i[0] = ~((hob << 8) | lob); stop.i[1] = *p; l = stop.l - strt.l; result = ((l<0)?4294967296.0 + (long)l : (long)l); return result / TimerResolution; } void wait(double val) { double current, strt = elapsedTime(); do { current = elapsedTime(); } while(current-strt < val/1000000.0); } void initTimer(void) { markStart(); delay(1); elapsedTime(); /* otherwise the first call to elapsedTime retunrs wrong */ } /*------------------------Graphics Routines--------------------*/ #define UP 72 #define DOWN 80 #define LEFT 75 #define RIGHT 77 #define ESC 27 #include #define XLIM 639 /* VGA mode 640 x 480 */ #define YLIM 479 #define XOFF 80 #define YOFF 40 #define XMIN XOFF /* border */ #define XMAX (XLIM-XOFF) #define YMIN YOFF #define YMAX (YLIM-YOFF) float xmin, ymin, xmax, ymax, dx, dy; void initialize(void) { int driver, mode, result; driver = DETECT; /* Request auto-detection */ initgraph(&driver, &mode, "" ); /* Enter graphics mode */ result = graphresult(); /* Read result of initialization */ if( result != grOk ){ /* Error occured during init */ printf(" Graphics System Error: %s\n", grapherrormsg(result) ); exit( 1 ); } } void setWorld(double x1, double y1, double x2, double y2) { /* Calculate the scale factors to be used by functions drawPoint etc. */ xmin = x1; ymin = y1; xmax = x2; ymax = y2; dx = (xmax - xmin) / (XMAX-XMIN); dy = (ymax - ymin) / (YMAX-YMIN); setcolor(WHITE); rectangle(XOFF-1, YOFF-1, XMAX+1, YMAX+1); } void drawPoint(double x, double y, int color) { int crtx, crty; crtx= XOFF + (int) ( (x-xmin) / dx); crty = (int) ( (y-ymin) / dy); crty = YLIM - (crty + YOFF); putpixel(crtx,crty,color); } void box(double x1, double y1, double x2, double y2, int color) { int ix1, iy1, ix2, iy2; ix1 = XOFF + (int) ( (x1-xmin) / dx); iy1 = YLIM - YOFF - (int) ( (y1-ymin) / dy); ix2 = XOFF + (int) ( (x2-xmin) / dx); iy2 = YLIM - YOFF - (int) ( (y2-ymin) / dy); setcolor(color); rectangle(ix1,iy1,ix2,iy2); } void block(double x1, double y1, double x2, double y2, int color) { int ix1, iy1, ix2, iy2; ix1 = XOFF + (int) ( (x1-xmin) / dx); iy1 = YLIM - YOFF - (int) ( (y1-ymin) / dy); ix2 = XOFF + (int) ( (x2-xmin) / dx); iy2 = YLIM - YOFF - (int) ( (y2-ymin) / dy); setfillstyle(SOLID_FILL,color); bar(ix1,iy1,ix2,iy2); } void drawLine(double x1, double y1, double x2, double y2) { int ix1, iy1, ix2, iy2; ix1 = XOFF + (int) ( (x1-xmin) / dx); iy1 = YLIM - YOFF - (int) ( (y1-ymin) / dy); ix2 = XOFF + (int) ( (x2-xmin) / dx); iy2 = YLIM - YOFF - (int) ( (y2-ymin) / dy); line(ix1,iy1,ix2,iy2); } void drawBar(double x1, double y1, double x2, double y2) { int ix1, iy1, ix2, iy2; ix1 = XOFF + (int) ( (x1-xmin) / dx); iy1 = YLIM - YOFF - (int) ( (y1-ymin) / dy); ix2 = XOFF + (int) ( (x2-xmin) / dx); iy2 = YLIM - YOFF - (int) ( (y2-ymin) / dy); bar(ix1,iy1,ix2,iy2); } void drawText(double x, double y, char *p) { int crtx, crty; crtx= XOFF + (int) ( (x-xmin) / dx); crty = (int) ( (y-ymin) / dy); crty = YLIM - (crty + YOFF); outtextxy(crtx,crty,p); } void drawGrid(char *xlabel, char *ylabel) { double x, y, dx, dy; char ss[20]; dx = (xmax - xmin) / 10; dy = (ymax - ymin) / 10; setcolor(GREEN); settextjustify(1,1); if(xlabel) drawText((xmin+xmax)/2, ymin-dy/2, xlabel); if(ylabel) { settextstyle(DEFAULT_FONT,1,1); drawText(xmin-dx, (ymin+ymax)/2, ylabel); settextstyle(DEFAULT_FONT,0,1); } for(x=xmin+dx; x < xmax; x += dx) { drawLine(x, ymin, x,ymax); sprintf(ss,"%4.0f",x); drawText(x, ymin-dy/4, ss); } for(y=ymin+dy; y < ymax; y += dy) { drawLine(xmin, y, xmax, y); sprintf(ss,"%4.0f",y); drawText(xmin-dx/2, y, ss); } settextjustify(0,0); dx /= 10; dy /= 10; for(x=xmin; x < xmax; x += dx) drawLine(x, 0, x, dy); for(y=ymin; y < ymax; y += dy) drawLine(0, y, dx, y); setcolor(WHITE); } /*--------------------------------------------------------------*/