00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #ifndef __GNUC__
00048 #ifndef __attribute__
00049 #define __attribute__(x)
00050 #endif
00051 #endif
00052
00053 static char __attribute__((unused)) ident[] = "$Id: stg.c,v 1.13 2001/10/30 23:31:03 paul_c Exp $";
00054
00055 #include "stg.h"
00056 #include "extintf.h"
00057
00058
00059
00060 unsigned short STG_BASE_ADDRESS = DEFAULT_STG_BASE_ADDRESS;
00061 int FIND_STG_BASE_ADDRESS=0;
00062
00063 #ifdef STG_8_AXES
00064 #define STG_MAX_AXIS 8
00065 #else
00066 #define STG_MAX_AXIS 4
00067 #endif
00068
00069 #if defined(rtlinux) || defined(rtai)
00070 #ifndef MODULE
00071 #define MODULE
00072 #endif
00073 #define DO_IT
00074 #endif
00075
00076 #ifdef LINUX
00077 #define DO_IT
00078
00079
00080
00081
00082
00083
00084
00085 #ifdef DEFINE_EXTERN_BEFORE_IO
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 #define extern
00097 #endif
00098
00099
00100
00101
00102
00103
00104 #include <sys/types.h>
00105 #include <unistd.h>
00106
00107 #endif
00108
00109 #ifdef DO_IT
00110
00111 #if defined(__KERNEL__) && defined(linux)
00112 #include <linux/kernel.h>
00113 #if !defined(rtai)
00114
00115
00116
00117 #include <linux/types.h>
00118 #include <linux/fs.h>
00119 #endif
00120 #endif
00121
00122 #if defined(linux) || defined(rtlinux) || defined(rtai)
00123 #include <sys/io.h>
00124 #endif
00125
00126
00127
00128 #ifndef LINUX_VERSION_CODE
00129 #include <linux/version.h>
00130 #endif
00131
00132 #ifndef __GLIBC__
00133 #include <features.h>
00134 #endif
00135
00136
00137 #ifndef KERNEL_VERSION
00138 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
00139 #endif
00140
00141
00142
00143
00144
00145 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0) || !defined(__GLIBC__) || __GLIBC__ < 2
00146 #include <asm/io.h>
00147 #endif
00148
00149 #else
00150
00151
00152
00153 #include <stdio.h>
00154
00155 static int iopl(int level)
00156 {
00157 return 0;
00158 }
00159
00160 static unsigned char inb(unsigned int port)
00161 {
00162 if (port >= STG_BASE_ADDRESS &&
00163 port <= STG_BASE_ADDRESS + 0x1f)
00164 {
00165 return 0;
00166 }
00167
00168 if (port >= STG_BASE_ADDRESS + 0x400 &&
00169 port <= STG_BASE_ADDRESS + 0x400 + 0x1f)
00170 {
00171 return 0;
00172 }
00173
00174 printf("inb: address out of bounds: %X\n", port);
00175 return 0;
00176 }
00177
00178 static void outb(unsigned char byte, unsigned int port)
00179 {
00180
00181 if (port == 0x80)
00182 {
00183 return;
00184 }
00185
00186 if (port >= STG_BASE_ADDRESS &&
00187 port <= STG_BASE_ADDRESS + 0x1f)
00188 {
00189 return;
00190 }
00191
00192 if (port >= STG_BASE_ADDRESS + 0x400 &&
00193 port <= STG_BASE_ADDRESS + 0x400 + 0x1f)
00194 {
00195 return;
00196 }
00197
00198 printf("outb: address out of bounds: %X\n", port);
00199 }
00200
00201 static unsigned short inw(unsigned int port)
00202 {
00203 if (port % 2)
00204 {
00205 printf("inw: alignment error: %X\n", port);
00206 return 0;
00207 }
00208
00209 if (port >= STG_BASE_ADDRESS &&
00210 port <= STG_BASE_ADDRESS + 0x1e)
00211 {
00212 return 0;
00213 }
00214
00215 if (port >= STG_BASE_ADDRESS + 0x400 &&
00216 port <= STG_BASE_ADDRESS + 0x400 + 0x1e)
00217 {
00218 return 0;
00219 }
00220
00221 printf("inw: address out of bounds: %X\n", port);
00222 return 0;
00223 }
00224
00225 static void outw(unsigned short word, unsigned int port)
00226 {
00227 if (port % 2)
00228 {
00229 printf("outw: alignment error: %X\n", port);
00230 return;
00231 }
00232
00233 if (port >= STG_BASE_ADDRESS &&
00234 port <= STG_BASE_ADDRESS + 0x1e)
00235 {
00236 return;
00237 }
00238
00239 if (port >= STG_BASE_ADDRESS + 0x400 &&
00240 port <= STG_BASE_ADDRESS + 0x400 + 0x1e)
00241 {
00242 return;
00243 }
00244
00245 printf("outw: address out of bounds: %X\n", port);
00246 return;
00247 }
00248
00249 #endif
00250
00251
00252 #define _outp(port,val) outb(val,port)
00253 #define outp(port,val) outb(val,port)
00254 #define _inp(port) inb(port)
00255 #define inp(port) inb(port)
00256 #define _inpw(port) inw(port)
00257 #define _outpw(port,val) outw(val,port)
00258
00259 static short int nIrq;
00260
00261 void SetIrq(short nRequestedIrq)
00262 {
00263 unsigned char byIntReg;
00264
00265 nIrq = nRequestedIrq;
00266
00267 byIntReg = 0x80;
00268
00269
00270
00271
00272
00273 switch (nRequestedIrq)
00274 {
00275 case 3: break;
00276
00277 case 5: byIntReg |= 4;
00278 break;
00279
00280 case 7: byIntReg |= 2;
00281 break;
00282
00283 case 9: byIntReg |= 6;
00284 break;
00285
00286 case 10: byIntReg |= 5;
00287 break;
00288
00289 case 11: byIntReg |= 7;
00290 break;
00291
00292 case 12: byIntReg |= 3;
00293 break;
00294
00295 case 15: byIntReg |= 1;
00296 break;
00297
00298 default: nIrq = 5;
00299 byIntReg |= 4;
00300
00301
00302 break;
00303 }
00304
00305 _outp(STG_BASE_ADDRESS + INTC, byIntReg);
00306 }
00307
00308 unsigned short BaseFind()
00309 {
00310 short i, j, k, l, ofs;
00311 unsigned short io_add;
00312
00313 for (i = 15; i >= 0; i--)
00314 {
00315 io_add = i * 0x20 + 0x200;
00316 if ((_inp(io_add + BRDTST) & 0x0f) == i)
00317 {
00318 k = 0;
00319 for (j = 7; j >= 0; j--)
00320 {
00321 ofs = (_inp(io_add + BRDTST) & 0xf0) / 16;
00322 l = 0;
00323 if (ofs > 7)
00324 l = 1;
00325 ofs = ofs & 7;
00326 if (l == 1)
00327 k += (1 << ofs);
00328 }
00329 if (k == 0x75) return io_add;
00330 }
00331 }
00332 return(0);
00333 }
00334
00335 short int Initialize(short int nRequestedIrq)
00336 {
00337
00338
00339
00340 _outp(STG_BASE_ADDRESS + MIO_2, 0x92);
00341
00342
00343 SetIrq(nRequestedIrq);
00344
00345
00346
00347
00348 _outp( STG_BASE_ADDRESS + ICW1, 0x1a );
00349
00350 _outp( STG_BASE_ADDRESS + ICW2, 0x00 );
00351
00352 _outp( STG_BASE_ADDRESS + OCW1, 0xff);
00353
00354
00355
00356 return 0;
00357 }
00358
00359 int StartADC(unsigned short wAxis)
00360 {
00361 if (wAxis > 7) {
00362 return -1;
00363 }
00364
00365
00366
00367 _inpw(STG_BASE_ADDRESS + ADC_0 + (wAxis << 1));
00368
00369
00370
00371 _outp(0x80, 0);
00372 _outp(0x80, 0);
00373 _outp(0x80, 0);
00374 _outp(0x80, 0);
00375
00376
00377 _outpw(STG_BASE_ADDRESS + ADC_0 + (wAxis << 1), 0);
00378
00379 return 0;
00380 };
00381
00382 short RawADC(unsigned short wAxis)
00383 {
00384 short ret;
00385 short j;
00386
00387 if (wAxis > 7)
00388 return -1;
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 for (j = 0; !(_inp(STG_BASE_ADDRESS + IRR) & 0x08) && (j < 1000); j++);
00403
00404 ret = _inpw(STG_BASE_ADDRESS + ADC_0 + (wAxis << 1));
00405
00406 if (ret & 0x1000)
00407 ret |= 0xf000;
00408 else
00409 ret &= 0xfff;
00410
00411 return ret;
00412 };
00413
00414 void EncoderInit()
00415 {
00416 unsigned int wAdd;
00417 unsigned int wAddTop;
00418
00419 #ifdef STG_8_AXES
00420 wAddTop = STG_BASE_ADDRESS + CNT6_C;
00421 #else
00422 wAddTop = STG_BASE_ADDRESS + CNT2_C;
00423 #endif
00424
00425 for (wAdd = STG_BASE_ADDRESS + CNT0_C; wAdd <= wAddTop; wAdd +=4)
00426 {
00427
00428
00429
00430 _outpw(wAdd, 0x2323);
00431
00432
00433
00434
00435 _outpw(wAdd, 0x6868);
00436
00437
00438
00439 _outpw(wAdd, 0x8080);
00440
00441
00442
00443 _outpw(wAdd, 0xc3c3);
00444 }
00445 }
00446
00447 void SelectInterruptPeriod(long lPeriodSelect)
00448 {
00449 _outp(STG_BASE_ADDRESS + TMRCMD, 0x56);
00450
00451 _outp(STG_BASE_ADDRESS + TIMER_1, 0xb4);
00452
00453 switch (lPeriodSelect)
00454 {
00455 case _500_MICROSECONDS:
00456 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00457
00458 _outp(STG_BASE_ADDRESS + TIMER_0, 0x14);
00459 _outp(STG_BASE_ADDRESS + TIMER_0, 0x00);
00460 break;
00461 case _1_MILLISECOND:
00462 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00463
00464 _outp(STG_BASE_ADDRESS + TIMER_0, 0x28);
00465 _outp(STG_BASE_ADDRESS + TIMER_0, 0x00);
00466 break;
00467 case _2_MILLISECONDS:
00468 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00469
00470 _outp(STG_BASE_ADDRESS + TIMER_0, 0x50);
00471 _outp(STG_BASE_ADDRESS + TIMER_0, 0x00);
00472 break;
00473 case _3_MILLISECONDS:
00474 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00475
00476 _outp(STG_BASE_ADDRESS + TIMER_0, 0x78);
00477 _outp(STG_BASE_ADDRESS + TIMER_0, 0x00);
00478 break;
00479 case _4_MILLISECONDS:
00480 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00481
00482 _outp(STG_BASE_ADDRESS + TIMER_0, 0xA0);
00483 _outp(STG_BASE_ADDRESS + TIMER_0, 0x00);
00484 break;
00485 case _5_MILLISECONDS:
00486 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00487
00488 _outp(STG_BASE_ADDRESS + TIMER_0, 0xC8);
00489 _outp(STG_BASE_ADDRESS + TIMER_0, 0x00);
00490 break;
00491 case _10_MILLISECONDS:
00492 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00493
00494 _outp(STG_BASE_ADDRESS + TIMER_0, 0x90);
00495 _outp(STG_BASE_ADDRESS + TIMER_0, 0x01);
00496 break;
00497 case _100_MILLISECONDS:
00498 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00499
00500 _outp(STG_BASE_ADDRESS + TIMER_0, 0xA0);
00501 _outp(STG_BASE_ADDRESS + TIMER_0, 0x0F);
00502 break;
00503 case _1_SECOND:
00504 _outp(STG_BASE_ADDRESS + TMRCMD, 0x34);
00505
00506 _outp(STG_BASE_ADDRESS + TIMER_0, 0x40);
00507 _outp(STG_BASE_ADDRESS + TIMER_0, 0x9c);
00508 break;
00509 default:
00510
00511 break;
00512 }
00513 };
00514
00515
00516
00517
00518
00519
00520
00521
00522 int RawDAC(short nAxis, double volts)
00523 {
00524 short nCounts;
00525
00526 if ( (nAxis > 7) || (nAxis < 0) )
00527 return -1;
00528
00529
00530 nCounts = (short) ((10.0 - volts) / 20.0 * 0x1FFF);
00531
00532 if (nCounts > 0x1FFF)
00533 {
00534 nCounts = 0x1FFF;
00535 }
00536 if (nCounts < 0)
00537 {
00538 nCounts = 0;
00539 }
00540
00541 _outpw(STG_BASE_ADDRESS + DAC_0 + (nAxis << 1), nCounts);
00542
00543 return 0;
00544 };
00545
00546 int EncoderLatch()
00547 {
00548 unsigned short wAdd;
00549 unsigned short wAddTop;
00550
00551 #ifdef STG_8_AXES
00552 wAddTop = STG_BASE_ADDRESS + CNT6_C;
00553 #else
00554 wAddTop = STG_BASE_ADDRESS + CNT2_C;
00555 #endif
00556
00557 for (wAdd = STG_BASE_ADDRESS + CNT0_C; wAdd <= wAddTop; wAdd +=4)
00558 {
00559 _outpw(wAdd, 0x0303);
00560 }
00561
00562 return 0;
00563 }
00564
00565 int EncReadAll(LONGBYTE * lbEnc)
00566 {
00567 WORDBYTE wbTransfer;
00568 static unsigned char byOldByte2[STG_MAX_AXIS];
00569 static unsigned char byEncHighByte[STG_MAX_AXIS];
00570 short i;
00571 unsigned int wAdd;
00572 unsigned int wAddTop;
00573
00574
00575
00576
00577
00578
00579
00580
00581 #ifdef STG_8_AXES
00582 wAddTop = STG_BASE_ADDRESS + CNT6_C;
00583 #else
00584 wAddTop = STG_BASE_ADDRESS + CNT2_C;
00585 #endif
00586
00587
00588 for (wAdd = STG_BASE_ADDRESS + CNT0_C; wAdd <= wAddTop; wAdd +=4)
00589 {
00590 _outpw(wAdd, 0x0101);
00591 }
00592
00593 for (i = 0; i < 3; i++)
00594 {
00595 wbTransfer.Word = _inpw(STG_BASE_ADDRESS + CNT0_D);
00596
00597 lbEnc[0].Byte[i] = wbTransfer.Byte.high;
00598 lbEnc[1].Byte[i] = wbTransfer.Byte.low;
00599
00600 wbTransfer.Word = _inpw(STG_BASE_ADDRESS + CNT2_D);
00601
00602 lbEnc[2].Byte[i] = wbTransfer.Byte.high;
00603 lbEnc[3].Byte[i] = wbTransfer.Byte.low;
00604
00605 #ifdef STG_8_AXES
00606 wbTransfer.Word = _inpw(STG_BASE_ADDRESS + CNT4_D);
00607
00608 lbEnc[4].Byte[i] = wbTransfer.Byte.high;
00609 lbEnc[5].Byte[i] = wbTransfer.Byte.low;
00610
00611 wbTransfer.Word = _inpw(STG_BASE_ADDRESS + CNT6_D);
00612
00613 lbEnc[6].Byte[i] = wbTransfer.Byte.high;
00614 lbEnc[7].Byte[i] = wbTransfer.Byte.low;
00615 #endif
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 for (i = 0; i < STG_MAX_AXIS; i++)
00631 {
00632
00633
00634 if ( ( (byOldByte2[i] & 0xc0) == 0xc0 )
00635 && ( (lbEnc[i].Byte[2] & 0xc0) == 0 )
00636 )
00637 byEncHighByte[i]++;
00638
00639
00640
00641 if ( ( (byOldByte2[i] & 0xc0) == 0 )
00642 && ( (lbEnc[i].Byte[2] & 0xc0) == 0xc0 )
00643 )
00644 byEncHighByte[i]--;
00645
00646 lbEnc[i].Byte[3] = byEncHighByte[i];
00647 byOldByte2[i] = lbEnc[i].Byte[2];
00648 }
00649
00650 return 0;
00651 }
00652
00653 void ResetIndexLatch()
00654 {
00655 _inp(STG_BASE_ADDRESS + ODDRST);
00656 _inp(STG_BASE_ADDRESS + BRDTST);
00657 }
00658
00659 static unsigned char byIndexPollAxis = 0;
00660 static unsigned char byIndexPulsePolarity = 1;
00661
00662 void SelectIndexAxis(unsigned char byAxis, unsigned char byPol)
00663 {
00664
00665
00666
00667 unsigned char byIntc;
00668
00669 byIndexPollAxis = byAxis;
00670 byIndexPulsePolarity = byPol;
00671 byAxis &= 0x6;
00672 byAxis <<= 3;
00673 byIntc = _inp(STG_BASE_ADDRESS + INTC);
00674
00675 byIntc &= ~(IXLVL | IXS1 | IXS0);
00676 byIntc |= byAxis;
00677 if (byPol != 0)
00678 byIntc |= IXLVL;
00679 _outp(STG_BASE_ADDRESS + INTC, byIntc);
00680 ResetIndexLatch();
00681
00682
00683
00684 }
00685
00686 unsigned char CurrentIRR()
00687 {
00688 outp(STG_BASE_ADDRESS + OCW3, 0x0a);
00689 return inp(STG_BASE_ADDRESS + IRR);
00690 }
00691
00692 int IndexPulseLatch()
00693 {
00694
00695
00696 unsigned char byIRR, byAxisMask;
00697
00698 byIRR = CurrentIRR();
00699 byAxisMask = (byIndexPollAxis & 1) ? LIXODD : LIXEVN;
00700 if (byIRR & byAxisMask)
00701 return 1;
00702 return 0;
00703 }
00704
00705 long RawDI()
00706 {
00707 IO32 xInBits;
00708
00709 xInBits.port.A = _inp(STG_BASE_ADDRESS + DIO_A);
00710 xInBits.port.B = _inp(STG_BASE_ADDRESS + DIO_B);
00711 xInBits.port.C = _inp(STG_BASE_ADDRESS + DIO_C);
00712 xInBits.port.D = _inp(STG_BASE_ADDRESS + DIO_D);
00713
00714 return xInBits.all;
00715 };
00716
00717 void RawDO(unsigned char byBitNumber, unsigned char by0or1, unsigned short nPort)
00718 {
00719 unsigned nOffset;
00720 unsigned char byData;
00721
00722 switch (nPort)
00723 {
00724 case 0:
00725 nOffset = DIO_A;
00726 break;
00727 case 1:
00728 nOffset = DIO_B;
00729 break;
00730 case 2:
00731 nOffset = DIO_C;
00732 break;
00733 case 3:
00734 nOffset = DIO_D;
00735 break;
00736 default:
00737 return;
00738 }
00739 byData = _inp(STG_BASE_ADDRESS + nOffset);
00740 if (by0or1 == 1)
00741 byData |= 1 << byBitNumber;
00742 else
00743 byData &= ~(1 << byBitNumber);
00744 _outp(STG_BASE_ADDRESS + nOffset, byData);
00745 };
00746
00747 void RawDOAll(IO32 xOutBits)
00748 {
00749 _outp(STG_BASE_ADDRESS + DIO_A, xOutBits.port.A);
00750 _outp(STG_BASE_ADDRESS + DIO_B, xOutBits.port.B);
00751 _outp(STG_BASE_ADDRESS + DIO_C, xOutBits.port.C);
00752 _outp(STG_BASE_ADDRESS + DIO_D, xOutBits.port.D);
00753 };
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767 void DIOdirection(short nSwDir)
00768 {
00769 unsigned char byHwDir;
00770 unsigned char bySaveIntc, bySaveIMR;
00771
00772 byHwDir = 0x9b;
00773
00774 if (nSwDir & 0x01)
00775 byHwDir &= ~A_OUT;
00776 if (nSwDir & 0x02)
00777 byHwDir &= ~B_OUT;
00778 if (nSwDir & 0x04)
00779 byHwDir &= ~C_LOW_OUT;
00780 if (nSwDir & 0x08)
00781 byHwDir &= ~C_HI_OUT;
00782 _outp(STG_BASE_ADDRESS + MIO_1, byHwDir);
00783
00784 bySaveIntc = _inp(STG_BASE_ADDRESS + INTC);
00785
00786
00787 byHwDir = 0x92;
00788 if (nSwDir & 0x10)
00789 byHwDir &= ~D_OUT;
00790 bySaveIMR = _inp(STG_BASE_ADDRESS + IMR);
00791 _outp(STG_BASE_ADDRESS + OCW1, 0xff);
00792 _outp(STG_BASE_ADDRESS + MIO_2, byHwDir);
00793 _outp(STG_BASE_ADDRESS + INTC, bySaveIntc);
00794 _outp(STG_BASE_ADDRESS + OCW1, bySaveIMR);
00795 };
00796
00797
00798
00799
00800 static double checkedOutputs[STG_MAX_AXIS];
00801
00802 #define STG_INIT_WAIT 1000
00803
00804 int stgMotInit(const char * stuff)
00805 {
00806 int t;
00807
00808 #ifdef LINUX
00809
00810 if (-1 == iopl(3))
00811 {
00812 return -1;
00813 }
00814 #endif
00815
00816 Initialize(5);
00817 EncoderInit();
00818
00819
00820 for (t = 0; t < STG_MAX_AXIS; t++)
00821 {
00822
00823 stgDacWrite(t, 0.0);
00824 }
00825
00826
00827 stgDioInit(0);
00828
00829
00830
00831
00832 for (t = 0; t < STG_INIT_WAIT; t++)
00833 {
00834
00835 _outp(0x80, 0);
00836 }
00837
00838 return 0;
00839 }
00840
00841 int stgMotQuit()
00842 {
00843 int t;
00844
00845 for (t = 0; t < STG_MAX_AXIS; t++)
00846 {
00847
00848 stgDacWrite(t, 0.0);
00849 }
00850
00851 return 0;
00852 }
00853
00854 int stgAdcNum(void)
00855 {
00856 return STG_MAX_AXIS;
00857 }
00858
00859 int stgAdcStart(int adc)
00860 {
00861 if (adc < 0 ||
00862 adc >= STG_MAX_AXIS) {
00863 return 0;
00864 }
00865
00866 StartADC((unsigned short) adc);
00867
00868 return 0;
00869 }
00870
00871 #define STG_ADC_WAIT_USEC 20
00872
00873 void stgAdcWait(void)
00874 {
00875 int t;
00876
00877 for (t = 0; t < STG_ADC_WAIT_USEC; t++) {
00878 _outp(0x80, 0);
00879 }
00880 }
00881
00882 int stgAdcRead(int adc, double * volts)
00883 {
00884 if (adc < 0 ||
00885 adc >= STG_MAX_AXIS) {
00886 return 0;
00887 }
00888
00889 *volts = (double) RawADC((unsigned short) adc);
00890
00891 return 0;
00892 }
00893
00894 int stgDacNum()
00895 {
00896 return STG_MAX_AXIS;
00897 }
00898
00899 int stgDacWrite(int dac, double volts)
00900 {
00901 if (dac < 0 ||
00902 dac >= STG_MAX_AXIS) {
00903 return 0;
00904 }
00905
00906 checkedOutputs[dac] = volts;
00907
00908 return RawDAC(dac, volts);
00909 }
00910
00911 int stgDacWriteAll(int max, double * volts)
00912 {
00913 int t;
00914 int smax;
00915
00916
00917 if (max > STG_MAX_AXIS) {
00918 smax = STG_MAX_AXIS;
00919 }
00920 else {
00921 smax = max;
00922 }
00923
00924 for (t = 0; t < smax; t++) {
00925 if (0 != stgDacWrite(t, volts[t])){
00926 return -1;
00927 }
00928 }
00929
00930 return 0;
00931 }
00932
00933 unsigned int stgEncoderIndexModel(void)
00934 {
00935 return EXT_ENCODER_INDEX_MODEL_MANUAL;
00936 }
00937
00938 int stgEncoderSetIndexModel(unsigned int model)
00939 {
00940 if (model != EXT_ENCODER_INDEX_MODEL_MANUAL)
00941 {
00942 return -1;
00943 }
00944
00945 return 0;
00946 }
00947
00948 int stgEncoderNum()
00949 {
00950 return STG_MAX_AXIS;
00951 }
00952
00953 int stgEncoderRead(int encoder, double * counts)
00954 {
00955 double allCounts[STG_MAX_AXIS];
00956
00957 if (encoder < 0 ||
00958 encoder >= STG_MAX_AXIS) {
00959 *counts = 0.0;
00960 return 0;
00961 }
00962
00963 stgEncoderReadAll(encoder + 1, allCounts);
00964
00965 *counts = allCounts[encoder];
00966
00967 return 0;
00968 }
00969
00970 int stgEncoderReadAll(int max, double * counts)
00971 {
00972 LONGBYTE lbEnc[STG_MAX_AXIS];
00973 int t;
00974 int smax;
00975
00976
00977
00978 if (max > STG_MAX_AXIS) {
00979 smax = STG_MAX_AXIS;
00980 }
00981 else {
00982 smax = max;
00983 }
00984
00985 EncoderLatch();
00986 EncReadAll(lbEnc);
00987
00988
00989 for (t = 0; t < smax; t++) {
00990 counts[t] = (double) lbEnc[t].Long;
00991 }
00992
00993 for (t = smax; t < max; t++) {
00994 counts[t] = 0.0;
00995 }
00996
00997 return 0;
00998 }
00999
01000 int stgEncoderResetIndex(int encoder)
01001 {
01002 if (encoder < 0 ||
01003 encoder >= STG_MAX_AXIS)
01004 {
01005 return 0;
01006 }
01007
01008 SelectIndexAxis(encoder, 1);
01009
01010 return 0;
01011 }
01012
01013 int stgEncoderReadLatch(int encoder, int * flag)
01014 {
01015 *flag = IndexPulseLatch();
01016
01017 return 0;
01018 }
01019
01020
01021 int stgEncoderReadLevel(int encoder, int * flag)
01022 {
01023 unsigned char byIRR, byAxisMask;
01024
01025 byIRR = CurrentIRR();
01026 byAxisMask = (byIndexPollAxis & 1) ? IXODD : IXEVN;
01027
01028 if (byIRR & byAxisMask)
01029 {
01030 *flag = 1;
01031 }
01032 else
01033 {
01034 *flag = 0;
01035 }
01036
01037 return 0;
01038 }
01039
01040
01041
01042
01043
01044
01045 #define HOME_0 0x00000001
01046 #define MIN_LIM_0 0x00000002
01047 #define MAX_LIM_0 0x00000004
01048 #define FAULT_0 0x00000008
01049 #define HOME_1 0x00000010
01050 #define MIN_LIM_1 0x00000020
01051 #define MAX_LIM_1 0x00000040
01052 #define FAULT_1 0x00000080
01053 #define HOME_2 0x00000100
01054 #define MIN_LIM_2 0x00000200
01055 #define MAX_LIM_2 0x00000400
01056 #define FAULT_2 0x00000800
01057 #define HOME_3 0x00001000
01058 #define MIN_LIM_3 0x00002000
01059 #define MAX_LIM_3 0x00004000
01060 #define FAULT_3 0x00008000
01061
01062 #ifdef STG_8_AXES
01063
01064 #define HOME_4 0x01000000
01065 #define MIN_LIM_4 0x02000000
01066 #define MAX_LIM_4 0x04000000
01067 #define FAULT_4 0x08000000
01068 #define HOME_5 0x10000000
01069 #define MIN_LIM_5 0x20000000
01070 #define MAX_LIM_5 0x40000000
01071 #define FAULT_5 0x80000000
01072
01073 #endif
01074
01075
01076 int stgMaxLimitSwitchRead(int axis, int * flag)
01077 {
01078 long bits;
01079 int retval = 0;
01080
01081 bits = RawDI();
01082 *flag = 0;
01083
01084 switch (axis)
01085 {
01086 case 0:
01087 if (bits & MAX_LIM_0)
01088 {
01089 *flag = 1;
01090 }
01091 break;
01092
01093 case 1:
01094 if (bits & MAX_LIM_1)
01095 {
01096 *flag = 1;
01097 }
01098 break;
01099
01100 case 2:
01101 if (bits & MAX_LIM_2)
01102 {
01103 *flag = 1;
01104 }
01105 break;
01106
01107 case 3:
01108 if (bits & MAX_LIM_3)
01109 {
01110 *flag = 1;
01111 }
01112 break;
01113
01114 #ifdef STG_8_AXES
01115 case 4:
01116 if (bits & MAX_LIM_4)
01117 {
01118 *flag = 1;
01119 }
01120 break;
01121
01122 case 5:
01123 if (bits & MAX_LIM_5)
01124 {
01125 *flag = 1;
01126 }
01127 break;
01128
01129 #endif
01130
01131 default:
01132 retval = -1;
01133 break;
01134 }
01135
01136 return retval;
01137 }
01138
01139
01140
01141 int stgMinLimitSwitchRead(int axis, int * flag)
01142 {
01143 long bits;
01144 int retval = 0;
01145
01146 bits = RawDI();
01147 *flag = 0;
01148
01149 switch (axis)
01150 {
01151 case 0:
01152 if (bits & MIN_LIM_0)
01153 {
01154 *flag = 1;
01155 }
01156 break;
01157
01158 case 1:
01159 if (bits & MIN_LIM_1)
01160 {
01161 *flag = 1;
01162 }
01163 break;
01164
01165 case 2:
01166 if (bits & MIN_LIM_2)
01167 {
01168 *flag = 1;
01169 }
01170 break;
01171
01172 case 3:
01173 if (bits & MIN_LIM_3)
01174 {
01175 *flag = 1;
01176 }
01177 break;
01178
01179 #ifdef STG_8_AXES
01180 case 4:
01181 if (bits & MIN_LIM_4)
01182 {
01183 *flag = 1;
01184 }
01185 break;
01186
01187 case 5:
01188 if (bits & MIN_LIM_5)
01189 {
01190 *flag = 1;
01191 }
01192 break;
01193
01194 #endif
01195
01196 default:
01197 retval = -1;
01198 break;
01199 }
01200
01201 return retval;
01202 }
01203
01204
01205 int stgHomeSwitchRead(int axis, int *flag)
01206 {
01207 long bits;
01208 int retval = 0;
01209
01210 bits = RawDI();
01211 *flag = 0;
01212
01213 switch (axis)
01214 {
01215 case 0:
01216 if (bits & HOME_0)
01217 {
01218 *flag = 1;
01219 }
01220 break;
01221
01222 case 1:
01223 if (bits & HOME_1)
01224 {
01225 *flag = 1;
01226 }
01227 break;
01228
01229 case 2:
01230 if (bits & HOME_2)
01231 {
01232 *flag = 1;
01233 }
01234 break;
01235
01236 case 3:
01237 if (bits & HOME_3)
01238 {
01239 *flag = 1;
01240 }
01241 break;
01242
01243 #ifdef STG_8_AXES
01244 case 4:
01245 if (bits & HOME_4)
01246 {
01247 *flag = 1;
01248 }
01249 break;
01250
01251 case 5:
01252 if (bits & HOME_5)
01253 {
01254 *flag = 1;
01255 }
01256 break;
01257
01258 #endif
01259
01260 default:
01261 retval = -1;
01262 break;
01263 }
01264
01265 return retval;
01266 }
01267
01268
01269 int stgAmpEnable(int axis, int enable)
01270 {
01271 if (axis < 0 || axis >= STG_MAX_AXIS)
01272 {
01273 return 0;
01274 }
01275
01276 RawDO(axis, (unsigned char) enable, 2);
01277
01278 return 0;
01279 }
01280
01281
01282 int stgAmpFault(int axis, int * flag)
01283 {
01284 long bits;
01285 int retval = 0;
01286
01287 bits = RawDI();
01288 *flag = 0;
01289
01290 switch (axis)
01291 {
01292 case 0:
01293 if (bits & FAULT_0)
01294 {
01295 *flag = 1;
01296 }
01297 break;
01298
01299 case 1:
01300 if (bits & FAULT_1)
01301 {
01302 *flag = 1;
01303 }
01304 break;
01305
01306 case 2:
01307 if (bits & FAULT_2)
01308 {
01309 *flag = 1;
01310 }
01311 break;
01312
01313 case 3:
01314 if (bits & FAULT_3)
01315 {
01316 *flag = 1;
01317 }
01318 break;
01319
01320 #ifdef STG_8_AXES
01321 case 4:
01322 if (bits & FAULT_4)
01323 {
01324 *flag = 1;
01325 }
01326 break;
01327
01328 case 5:
01329 if (bits & FAULT_5)
01330 {
01331 *flag = 1;
01332 }
01333 break;
01334
01335 #endif
01336
01337 default:
01338 retval = -1;
01339 break;
01340 }
01341
01342 return retval;
01343 }
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450 int stgDioInit(const char * stuff)
01451 {
01452
01453 DIOdirection(0x0C);
01454
01455 return 0;
01456 }
01457
01458 int stgDioQuit()
01459 {
01460 return 0;
01461 }
01462
01463 int stgDioMaxInputs()
01464 {
01465 return 24;
01466 }
01467
01468 int stgDioMaxOutputs()
01469 {
01470 return 24;
01471 }
01472
01473 int stgDioRead(int index, int *value)
01474 {
01475 unsigned char byte;
01476 unsigned char mask;
01477
01478 mask = 1 << (index % 8);
01479
01480
01481 if (index >= 0 && index < 8)
01482 {
01483 byte = _inp(STG_BASE_ADDRESS + DIO_A);
01484 *value = (byte & mask ? 1 : 0);
01485 return 0;
01486 }
01487
01488
01489 if (index >= 8 && index < 16)
01490 {
01491 byte = _inp(STG_BASE_ADDRESS + DIO_B);
01492 *value = (byte & mask ? 1 : 0);
01493 return 0;
01494 }
01495
01496
01497 if (index >= 16 && index < 24)
01498 {
01499 byte = _inp(STG_BASE_ADDRESS + DIO_D);
01500 *value = (byte & mask ? 1 : 0);
01501 return 0;
01502 }
01503
01504
01505 *value = 0;
01506 return -1;
01507 }
01508
01509
01510 int stgDioWrite(int index, int value)
01511 {
01512 if (index < 0 || index >= 8)
01513 {
01514 return -1;
01515 }
01516
01517 RawDO(index, (unsigned char) value, 2);
01518
01519 return 0;
01520 }
01521
01522
01523 int stgDioCheck(int index, int *value)
01524 {
01525 unsigned char byte;
01526 unsigned char mask;
01527
01528 if (index < 0 || index >= 8)
01529 {
01530 *value = 0;
01531 return -1;
01532 }
01533
01534 byte = _inp(STG_BASE_ADDRESS + DIO_C);
01535 mask = 1 << index;
01536
01537 *value = (byte & mask ? 1 : 0);
01538
01539 return 0;
01540 }
01541
01542
01543 int stgDioByteRead(int index, unsigned char *byte)
01544 {
01545 if (index == 0)
01546 {
01547 *byte = _inp(STG_BASE_ADDRESS + DIO_A);
01548 return 0;
01549 }
01550
01551 if (index == 1)
01552 {
01553 *byte = _inp(STG_BASE_ADDRESS + DIO_B);
01554 return 0;
01555 }
01556
01557 if (index == 2)
01558 {
01559 *byte = _inp(STG_BASE_ADDRESS + DIO_D);
01560 return 0;
01561 }
01562
01563 *byte = 0;
01564 return -1;
01565 }
01566
01567
01568 int stgDioShortRead(int index, unsigned short *sh)
01569 {
01570 unsigned char lo, hi;
01571
01572 if (index == 0)
01573 {
01574 lo = _inp(STG_BASE_ADDRESS + DIO_A);
01575 hi = _inp(STG_BASE_ADDRESS + DIO_B);
01576
01577 *sh = (hi << 8) + lo;
01578 return 0;
01579 }
01580
01581 if (index == 1)
01582 {
01583 lo = _inp(STG_BASE_ADDRESS + DIO_D);
01584
01585 *sh = lo;
01586 return 0;
01587 }
01588
01589 *sh = 0;
01590 return -1;
01591 }
01592
01593
01594 int stgDioWordRead(int index, unsigned int *word)
01595 {
01596 if (index != 0)
01597 {
01598 *word = 0;
01599 return -1;
01600 }
01601
01602 *word = _inp(STG_BASE_ADDRESS + DIO_D) << 16;
01603 *word += _inp(STG_BASE_ADDRESS + DIO_B) << 8;
01604 *word += _inp(STG_BASE_ADDRESS + DIO_A);
01605
01606 return 0;
01607 }
01608
01609
01610 int stgDioByteWrite(int index, unsigned char byte)
01611 {
01612 if (index == 0)
01613 {
01614 _outp(STG_BASE_ADDRESS + DIO_C, byte);
01615 return 0;
01616 }
01617
01618 return -1;
01619 }
01620
01621
01622 int stgDioShortWrite(int index, unsigned short sh)
01623 {
01624 return -1;
01625 }
01626
01627
01628 int stgDioWordWrite(int index, unsigned int word)
01629 {
01630 return -1;
01631 }
01632
01633
01634 int stgDioByteCheck(int index, unsigned char *byte)
01635 {
01636 if (index == 0)
01637 {
01638 *byte = _inp(STG_BASE_ADDRESS + DIO_C);
01639 return 0;
01640 }
01641
01642 *byte = 0;
01643 return -1;
01644 }
01645
01646
01647 int stgDioShortCheck(int index, unsigned short *sh)
01648 {
01649 *sh = 0;
01650 return -1;
01651 }
01652
01653
01654 int stgDioWordCheck(int index, unsigned int *word)
01655 {
01656 *word = 0;
01657 return -1;
01658 }
01659
01660 int stgAioInit(const char * stuff)
01661 {
01662
01663 return 0;
01664 }
01665
01666 int stgAioQuit()
01667 {
01668 return 0;
01669 }
01670
01671 int stgAioMaxInputs()
01672 {
01673 return 8;
01674 }
01675
01676 int stgAioMaxOutputs()
01677 {
01678 return STG_MAX_AXIS;
01679 }
01680
01681 int stgAioStart(int index)
01682 {
01683 return stgAdcStart(index);
01684 }
01685
01686 void stgAioWait(void)
01687 {
01688 stgAdcWait();
01689 }
01690
01691 int stgAioRead(int index, double *volts)
01692 {
01693 return stgAdcRead(index, volts);
01694 }
01695
01696 int stgAioWrite(int index, double volts)
01697 {
01698 return stgDacWrite(index, volts);
01699 }
01700
01701 int stgAioCheck(int index, double *volts)
01702 {
01703 if (index < 0 || index >= STG_MAX_AXIS) {
01704 *volts = 0.0;
01705 return 0;
01706 }
01707
01708
01709 *volts = checkedOutputs[index];
01710 return 0;
01711 }
01712
01713 int stgModel()
01714 {
01715 return 1;
01716 }