Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

stgmembs.c File Reference

#include "locdefs.h"
#include "offsets.h"
#include "stgdefs.h"
#include "locsysio.h"

Include dependency graph for stgmembs.c:

Include dependency graph

Go to the source code of this file.

Defines

#define __attribute__(x)
#define assert(a)

Functions

char __attribute__ ((unused)) ident[]="$Id
void fOutPW (unsigned short port, unsigned short data)
unsigned char fInP (unsigned short port)
unsigned short fInPW (unsigned short port)
unsigned short BaseAddress (void)
unsigned short GetBoardPresence (void)
unsigned short GetAxes (void)
unsigned short GetIrq (void)
unsigned short GetAddr (void)
unsigned short GetModel (void)
void ServoToGoConstructor (unsigned short wRequestedIrq)
void ServoToGoDestructor (void)
void SetIrq (unsigned short wRequestedIrq)
unsigned short BaseFind (void)
unsigned short BrdtstOK (unsigned short BaseAddress)
void Initialize (unsigned short wRequestedIrq)
void StartADC (unsigned short wAxis)
short SpinReadADC (unsigned short wAxis)
long ReadADC (unsigned short wAxis, short *counts_ptr)
void EncoderInit (void)
void SelectInterruptPeriod (long lPeriodSelect)
void RawDAC (unsigned short nAxis, long lCounts)
void EncReadAll (LONGBYTE *lbEnc)
void ResetIndexLatch ()
void ResetIndexLatches (unsigned char byLatchBits)
void SelectIndexAxis (unsigned char byAxis)
void SelectIndexAxisWithPolarity (unsigned char byAxis, unsigned char byPol)
void SelectIndexOrExtLatch (unsigned char bySelectBits)
void EnableCounterLatchOnIndexOrExt (unsigned char bySelectBits)
unsigned char CurrentIRR (void)
unsigned short IndexPulseLatch (void)
unsigned char GetIndexLatches ()
unsigned long RawDIAll ()
unsigned char RawDIBitPort (unsigned char byBitNumber, short nPort)
unsigned char RawDIPort (short nPort)
void RawDOAll (unsigned long lOutBits)
void RawDOBitValPort (unsigned char byBitNumber, unsigned char bySet0or1, unsigned short nPort)
void RawDOBytePort (unsigned char byData, short nPort)
short PortBits2Index (short nPort)
void DigitalOut1 (unsigned char byData, short nPortBits)
void DigitalOut2 (unsigned char byBitNumber, unsigned char bySet0or1, unsigned short nPortBits)
void DioDirection1 (unsigned short nPortBits, unsigned short nDirection)
void DioDirection2 (const unsigned short nSwDir)
void SetDDir (unsigned short nSwDir)
void MotSim (void)
void AutoZeroAdc (void)
void DontAutoZeroAdc (void)
void CalADC (void)
void SetEncoderCounts (unsigned short nAxis, long lCounts)
void EncoderLatch (void)
void EncoderResetAddr (void)
unsigned char GetSELDI ()
unsigned char GetIDLEN ()
unsigned char GetCNTRL0 ()
unsigned char GetCNTRL1 ()
void ResetWatchdogLatch ()
unsigned char GetBRDTST ()
short IndexPulse (void)
void StopTimer ()
void Timer2Delay (unsigned short counts)
void StartTimer2TerminalCount (unsigned short count)
void StartTimer2RTI (unsigned short count)
unsigned short ReadTimer2TerminalCount (void)
short PollTimer2 (void)
void MaskTimer2Interrupt ()
void UnMaskTimer2Interrupt ()
void StartInterrupts (void)
void StopInterrupts (void)

Variables

unsigned short wBaseAddress
unsigned short wIrq
unsigned short wModel
unsigned short wNoBoardFlag
unsigned short wAxesInSys
unsigned short wSaveDirs
unsigned char byIndexPollAxis
unsigned char byIndexPulsePolarity
long lSimDac [MAX_AXIS]
long lSimEnc [MAX_AXIS]
const int aPortOffset_1 [] = {DIO_A, DIO_B, DIO_C, DIO_D}
const int aPortOffset_2 [] = {PORT_A, PORT_B, PORT_C, PORT_D}
unsigned char byEncHighByte [MAX_AXIS]
unsigned char byOldByte2 [MAX_AXIS]


Define Documentation

#define __attribute__  
 

Definition at line 27 of file stgmembs.c.

#define assert a   
 

Referenced by DioDirection1().


Function Documentation

void AutoZeroAdc void   
 

Definition at line 1316 of file stgmembs.c.

01317 {
01318     // set the Analog to Digital converter to autozero on each conversion
01319 
01320     if (wModel == MODEL1)
01321         fOutP(wBaseAddress + INTC, fInP(wBaseAddress + INTC) & ~AUTOZERO);
01322     else   // MODEL2
01323         fOutP(wBaseAddress + CNTRL0, fInP(wBaseAddress + CNTRL0) | CNTRL0_AZ);
01324 }

unsigned short BaseAddress void   
 

Definition at line 79 of file stgmembs.c.

00080 {
00081   return wBaseAddress;
00082 }

unsigned short BaseFind void   
 

Definition at line 197 of file stgmembs.c.

00198 {
00199    short i;
00200    unsigned short io_add;
00201 
00202    for (i = 15; i >= 0; i--)                    // search all possible addresses
00203    {
00204        io_add = i * 0x20 + 0x200;
00205        if ( BrdtstOK(io_add) )
00206         return io_add;
00207    }
00208    return(0);
00209 }

unsigned short BrdtstOK unsigned short    BaseAddress
 

Definition at line 219 of file stgmembs.c.

Referenced by BaseFind().

00220 {
00221     unsigned short BrdtstAddress;
00222     unsigned short SerSeq, HighNibble;
00223     int j;
00224 
00225     BrdtstAddress = BaseAddress + BRDTST;
00226 
00227     SerSeq = 0;
00228     for ( j = 7; j >= 0; j--)
00229     {
00230         HighNibble = fInP(BrdtstAddress) >> 4;
00231         if (HighNibble & 8)     // is SER set
00232         {
00233            // shift bit to position specifed by Q2, Q1, Q0
00234            // which are the lower three bits.  Put bit in SerSeq.
00235            SerSeq |= 1 << (HighNibble & 7);
00236         }
00237     }
00238     if (SerSeq == 0x75)        // SER sequence is 01110101
00239     {
00240         wModel = MODEL1;
00241         return 1;              //true
00242     }
00243     if (SerSeq == 0x74)        // SER sequence is 01110100
00244     {
00245         wModel = MODEL2;
00246         return 1;              // true
00247     }
00248 //    wModel = MODEL_NO_ID;
00249     return 0;  // false
00250 }

void CalADC void   
 

Definition at line 1336 of file stgmembs.c.

01337 {
01338     // Start calibration cycle on ADC chip
01339 
01340     unsigned char Cntrl0;
01341 
01342     if (wModel == MODEL2)   // this function only in Model 2 board.
01343     {
01344         Cntrl0 = fInP(wBaseAddress + CNTRL0) & 0x07;       // save irq
01345         fOutP(wBaseAddress + CNTRL0, Cntrl0);              // cal is low
01346         // cal pulse should be 60 ns.  The ISA bus is 10 MHz. or 100 ns.
01347         // so we can just set it back high.
01348         fOutP(wBaseAddress + CNTRL0, Cntrl0 | 0x08);       // cal is high
01349     }
01350 }

unsigned char CurrentIRR void   
 

Definition at line 903 of file stgmembs.c.

00904 {
00905     fOutP(wBaseAddress + OCW3, 0x0a);           // IRR on next read
00906     return fInP(wBaseAddress + IRRreg);
00907 }

void DigitalOut1 unsigned char    byData,
short    nPortBits
 

Definition at line 1138 of file stgmembs.c.

01139 {
01140     RawDOBytePort(byData, PortBits2Index(nPortBits));
01141 }

void DigitalOut2 unsigned char    byBitNumber,
unsigned char    bySet0or1,
unsigned short    nPortBits
 

Definition at line 1143 of file stgmembs.c.

01145 {
01146     RawDOBitValPort(byBitNumber, bySet0or1, PortBits2Index(nPortBits));
01147 }

void DioDirection1 unsigned short    nPortBits,
unsigned short    nDirection
 

Definition at line 1158 of file stgmembs.c.

01159 {
01160   unsigned short nSwDir;  
01161   // sometimes you want to set the direction of a port, but may not know
01162     // what direction other ports are.  Here we select the port (or ports)
01163     // that we want to set the direction of, in nPortBits.  Then the direction,
01164     // either input or output, with nDirection.
01165     //
01166 
01167     assert(nDirection <= 1);      // direction is either 0 or 1
01168     if (nDirection > 1)
01169         return;
01170 
01171     nSwDir = wSaveDirs;
01172 
01173     if (nDirection == STG_PORT_OUTPUT)
01174         nSwDir |= nPortBits;
01175     else
01176         nSwDir &= ~nPortBits;
01177 
01178     DioDirection2(nSwDir);
01179 }

void DioDirection2 const unsigned short    nSwDir
 

Definition at line 1193 of file stgmembs.c.

Referenced by DioDirection1(), ServoToGoDestructor(), and stgDioInit().

01194 {
01195     unsigned char byHwDir;                   // direction bits for hardware
01196     unsigned long lCurrentData;
01197 
01198     if (wNoBoardFlag == NO_BOARD)
01199     {
01200         return;
01201     }
01202 
01203     // get the current data in the I/O ports.  We'll replace it when we're
01204     // done.  When you change a port to output, it will start at what the
01205     // input was (usually high).  This way, bits won't change (except for a
01206     // glitch) when a port is set to output.
01207 
01208     lCurrentData = RawDIAll();
01209 
01210     byHwDir = 0x9b;                          // initially all ports input
01211 
01212     if (nSwDir & STG_PORT_A)                 // check the bit for A out
01213          byHwDir &= ~A_DIR_BIT;                  // if output, set bit to 0
01214     if (nSwDir & STG_PORT_B)
01215          byHwDir &= ~B_DIR_BIT;
01216     if (nSwDir & STG_PORT_C_LO)
01217          byHwDir &= ~C_LOW_DIR_BIT;
01218     if (nSwDir & STG_PORT_C_HI)
01219          byHwDir &= ~C_HI_DIR_BIT;
01220 
01221     fOutP(wBaseAddress + ABC_DIR, byHwDir); // set direction for A, B and C
01222 
01223     SetDDir(nSwDir);
01224     wSaveDirs = nSwDir;                     // save, mostly for other function
01225     RawDOAll(lCurrentData);
01226 }

void DontAutoZeroAdc void   
 

Definition at line 1326 of file stgmembs.c.

01327 {
01328     // set the Analog to Digital converter to NOT autozero
01329 
01330     if (wModel == MODEL1)
01331         fOutP(wBaseAddress + INTC, fInP(wBaseAddress + INTC) | AUTOZERO);
01332     else   // MODEL2
01333         fOutP(wBaseAddress + CNTRL0, fInP(wBaseAddress + CNTRL0) & ~CNTRL0_AZ);
01334 }

void EnableCounterLatchOnIndexOrExt unsigned char    bySelectBits
 

Definition at line 892 of file stgmembs.c.

00893 {
00894     // routine for Model 2
00895     fOutP(wBaseAddress + IDLEN, bySelectBits);
00896 }

void EncReadAll LONGBYTE   lbEnc
 

Definition at line 731 of file stgmembs.c.

Referenced by EncoderInit(), ppmcEncoderReadAll(), and stgEncoderReadAll().

00732 {
00733     WORDBYTE wbTransfer;
00734     unsigned short add;
00735     short i;
00736     int max_axes = wAxesInSys;
00737     unsigned short maxAdd;
00738     if(max_axes != 8)
00739       {
00740         max_axes = 4;
00741       }
00742 
00743 //    static unsigned char byOldByte2[MAX_AXIS];
00744 //    static unsigned char byEncHighByte[MAX_AXIS];
00745 
00746     if (wNoBoardFlag == NO_BOARD)
00747     {
00748         for (i = 0; i < 8; i++)
00749         {
00750             lbEnc[i].Long = lSimEnc[i];
00751         }
00752         return;
00753     }
00754 
00755     // Disable interrupts here?  No, the timer will latch new data in the
00756     // hardware anyway.  Maybe we should stop the timer?  In an interrupt
00757     // service routine, you're synchronized with the timer; so the readings
00758     // will never change while you're reading them.  If you're polling, you
00759     // would first latch the encoder counts with the EncoderLatch() function.
00760     // But, the timer could latch the counts again, in the middle of the read.
00761     // A critical section will help in some extreme cases.
00762 
00763     // reset counter internal addr ptr to point to first byte
00764     maxAdd = (wBaseAddress + ((max_axes>4)?CNT6_C:CNT2_D));
00765     for (add = wBaseAddress + CNT0_C; 
00766          add <= maxAdd;
00767          add +=4)
00768         fOutPW(add, 0x0101);
00769 
00770     for (i = 0; i < 3; i++)            // 24 bits means get 3 bytes each
00771     {
00772         wbTransfer.Word = fInPW(wBaseAddress + CNT0_D);
00773 
00774         lbEnc[0].Byte[i] = wbTransfer.Byte.high;
00775         lbEnc[1].Byte[i] = wbTransfer.Byte.low;
00776 
00777         wbTransfer.Word = fInPW(wBaseAddress + CNT2_D);
00778 
00779         lbEnc[2].Byte[i] = wbTransfer.Byte.high;
00780         lbEnc[3].Byte[i] = wbTransfer.Byte.low;
00781 
00782         if(max_axes >= 8)
00783           {
00784             wbTransfer.Word = fInPW(wBaseAddress + CNT4_D);
00785             
00786             lbEnc[4].Byte[i] = wbTransfer.Byte.high;
00787             lbEnc[5].Byte[i] = wbTransfer.Byte.low;
00788 
00789             wbTransfer.Word = fInPW(wBaseAddress + CNT6_D);
00790             
00791             lbEnc[6].Byte[i] = wbTransfer.Byte.high;
00792             lbEnc[7].Byte[i] = wbTransfer.Byte.low;
00793           }
00794     }
00795 
00796     // maintain the high byte, to extend the counter to 32 bits
00797     //
00798     // base decisions to increment or decrement the high byte
00799     // on the highest 2 bits of the 24 bit value.  To get the
00800     // highest 2 bits, use 0xc0 as a mask on byte [2] (the third
00801     // byte).
00802 
00803     for (i = 0; i < max_axes; i++)
00804     {
00805         // check for -1 to 0 transition
00806 
00807         if (    ( (byOldByte2[i]    & 0xc0) == 0xc0 ) // 11xxxxxx
00808              && ( (lbEnc[i].Byte[2] & 0xc0) == 0 )    // 00xxxxxx
00809            )
00810            byEncHighByte[i]++;
00811 
00812         // check for 0 to -1 transition
00813 
00814         if (    ( (byOldByte2[i]    & 0xc0) == 0 )    // 00xxxxxx
00815              && ( (lbEnc[i].Byte[2] & 0xc0) == 0xc0 ) // 11xxxxxx
00816            )
00817            byEncHighByte[i]--;
00818 
00819         lbEnc[i].Byte[3] = byEncHighByte[i];
00820         byOldByte2[i] = lbEnc[i].Byte[2];    // current byte 2 becomes old one
00821     }
00822 };

void EncoderInit void   
 

Definition at line 462 of file stgmembs.c.

00463 {
00464     LONGBYTE enc[8];
00465     unsigned short wAdd,wA;
00466     unsigned short const wTestPat = 0x5aa5;
00467     
00468     if (wNoBoardFlag == NO_BOARD)
00469     {
00470         wAxesInSys = MAX_AXIS;
00471         return;
00472     }
00473 
00474     // It is possible that the encoder counts are being held by battery
00475     // backup, so we'll read the encoders, and save the values
00476     // Then we'll initialize the encoder chips, since it's more likely that
00477     // the ecoders were not kept alive by battery and need to be initialized
00478 
00479     EncReadAll(enc);
00480 
00481     // probably the right thing is to sign extend the 24 bits, so, instead
00482     // of a 24 bit unsigned count, we have +/- 23 bits.
00483 
00484 //    for ( i = 0; i < 8; i++)
00485 //    {
00486 //        byEncHighByte[i] = enc[i].Byte[2] & 0x80 ? 0xff : 0;
00487 //        byOldByte2[i] = enc[i].Byte[2];
00488 //    }
00489 
00490     for (wAdd = wBaseAddress + CNT0_C;
00491                                  wAdd <= wBaseAddress + CNT6_C; wAdd +=4)
00492     {
00493         // we're going to be slick and do two chips at a time, that's why
00494         // the registers are arranged data, data, control, control.  You
00495         // can do two at a time, by using word operations, instead of
00496         // byte operations.  Not a big deal for initializing, but reading is
00497         // done pretty often.
00498 
00499         fOutPW(wAdd, 0x2020);   // master reset
00500 
00501         // Set Counter Command Register - Input Control, OL Load (P3),
00502         // and Enable Inputs A and B (INA/B).
00503 
00504         fOutPW(wAdd, 0x6868);
00505 
00506         // Set Counter Command Register - Output Control
00507 
00508         fOutPW(wAdd, 0x8080);
00509 
00510         // Set Counter Command Register - Quadrature
00511 
00512         fOutPW(wAdd, 0xc3c3);
00513 
00514         fOutPW(wAdd, 0x0404);  //reset counter to zero
00515     }
00516 
00517     //  Figure out how many axes are on the card
00518 
00519     for ( wA = wBaseAddress + CNT0_D; wA <= wBaseAddress + CNT6_D; wA +=4)
00520     {
00521 
00522         // reset address pointer
00523 
00524         fOutPW(wA + 2, 0x0101);
00525 
00526         // write a pattern to the preset register
00527 
00528         fOutPW(wA, wTestPat);
00529         fOutPW(wA, wTestPat);
00530         fOutPW(wA, wTestPat);
00531 
00532         // transfer the preset register to the count register
00533 
00534         fOutPW(wA + 2, 0x0909);
00535 
00536         // transfer counter to output latch
00537 
00538         fOutPW(wA + 2, 0x0202);
00539 
00540         // read the output latch and see if it matches
00541 
00542         if (fInPW(wA) != wTestPat)
00543             break;
00544         if (fInPW(wA) != wTestPat)
00545             break;
00546         if (fInPW(wA) != wTestPat)
00547             break;
00548 
00549         // now replace the values that you saved previously, in case the
00550         // encoder was battery backed up
00551 
00552         fOutP(wA, enc[wAxesInSys].Byte[0]);
00553         fOutP(wA, enc[wAxesInSys].Byte[1]);
00554         fOutP(wA, enc[wAxesInSys].Byte[2]);
00555 
00556         fOutP(wA + 1, enc[wAxesInSys + 1].Byte[0]);
00557         fOutP(wA + 1, enc[wAxesInSys + 1].Byte[1]);
00558         fOutP(wA + 1, enc[wAxesInSys + 1].Byte[2]);
00559 
00560         // transfer the preset register to the count register
00561 
00562         fOutPW(wA + 2, 0x0909);
00563 
00564         wAxesInSys += 2;
00565 
00566         // write zeros to preset register, we don't want to do a master reset
00567         // (MRST), because then we would need to re-initialize the counter
00568 
00569 //        fOutPW(wA, 0);
00570 //        fOutPW(wA, 0);
00571 //        fOutPW(wA, 0);
00572 
00573         // reset counter, BRW and CRY and address pointer (RADR)
00574 
00575 //        fOutPW(wA + 2, 0x0505);
00576     }
00577 };

void EncoderLatch void   
 

Definition at line 1386 of file stgmembs.c.

01387 {
01388 #if 0
01389   unsigned short wAdd;
01390 #endif
01391     int max_axes = wAxesInSys;
01392     if (wNoBoardFlag == NO_BOARD)
01393     {
01394         return;
01395     }
01396     if(max_axes != 8)
01397       {
01398         max_axes = 4;
01399       }
01400 
01401    // normally you'll have the timer latch the data in hardware, but
01402    // if the timer isn't running, we need to latch it ourselves.
01403 #if 0
01404    for ( wAdd = wBaseAddress + CNT0_C; wAdd <= wBaseAddress + CNT6_C; wAdd +=4)
01405        fOutPW(wAdd, 0x0303);
01406 #endif
01407 
01408   /* BUG FIX-- don't go past 4 axes on 4 axis board */
01409   fOutPW(wBaseAddress + CNT0_C, 0x0303);
01410   fOutPW(wBaseAddress + CNT2_C, 0x0303);
01411   if (max_axes > 4) {
01412     fOutPW(wBaseAddress + CNT4_C, 0x0303);
01413     fOutPW(wBaseAddress + CNT6_C, 0x0303);
01414   }
01415 
01416 };

void EncoderResetAddr void   
 

Definition at line 1423 of file stgmembs.c.

01424 {
01425   unsigned short wAdd;
01426 
01427     if (wNoBoardFlag == NO_BOARD)
01428     {
01429         return;
01430     }
01431 
01432    // This function resets all the counter's internal address pointers to point
01433    // to the first byte in the 3 byte sequence
01434 
01435    for (wAdd = wBaseAddress + CNT0_C; wAdd <= wBaseAddress + CNT6_C; wAdd +=4)
01436        fOutPW(wAdd, 0x0101);
01437 };

unsigned short GetAddr void   
 

Definition at line 87 of file stgmembs.c.

00087 {return wBaseAddress;};

unsigned short GetAxes void   
 

Definition at line 85 of file stgmembs.c.

00085 {return wAxesInSys;};

unsigned char GetBRDTST void   
 

Definition at line 1468 of file stgmembs.c.

01469 {
01470     return fInP(wBaseAddress + BRDTST);
01471 }

unsigned short GetBoardPresence void   
 

Definition at line 84 of file stgmembs.c.

00084 {return wNoBoardFlag;};

unsigned char GetCNTRL0 void   
 

Definition at line 1449 of file stgmembs.c.

01450 {
01451     return fInP(wBaseAddress + CNTRL0);
01452 }

unsigned char GetCNTRL1 void   
 

Definition at line 1454 of file stgmembs.c.

01455 {
01456     return fInP(wBaseAddress + CNTRL1);
01457 }

unsigned char GetIDLEN void   
 

Definition at line 1444 of file stgmembs.c.

01445 {
01446     return fInP(wBaseAddress + IDLEN);
01447 }

unsigned char GetIndexLatches void   
 

Definition at line 938 of file stgmembs.c.

00939 {
00940     // routine for Model 2 board
00941 
00942     return fInP(wBaseAddress + IDL);
00943 }

unsigned short GetIrq void   
 

Definition at line 86 of file stgmembs.c.

00086 {return wIrq;};

unsigned short GetModel void   
 

Definition at line 88 of file stgmembs.c.

00088 {return wModel;};

unsigned char GetSELDI void   
 

Definition at line 1439 of file stgmembs.c.

01440 {
01441     return fInP(wBaseAddress + SELDI);
01442 }

short IndexPulse void   
 

Definition at line 1478 of file stgmembs.c.

01479 {
01480     // poll for the index pulse of the axis that was previously set up.
01481     // Normally you would look at the latched pulse.  This function will
01482     // probably only get used during testing.
01483 
01484     unsigned char byIRR, byAxisMask;
01485 
01486     byIRR = CurrentIRR();
01487     byAxisMask = (byIndexPollAxis & 1) ? IXODD : IXEVN;  // even or odd axis?
01488 
01489     // The raw index pulse isn't inverted by the hardware if the index pulse is
01490     // low active (only the latched pulse is).  For consistancy, we'll invert
01491     // the pulse in software.
01492 
01493     if (byIndexPulsePolarity == 0)                       // if pulse is low true
01494         byIRR ^= byAxisMask;                             // flip bit
01495 
01496     if (byIRR & byAxisMask)                              // check index pulse
01497         return 1;
01498     return 0;
01499 }

unsigned short IndexPulseLatch void   
 

Definition at line 914 of file stgmembs.c.

00915 {
00916     // routine for Model 1 board
00917 
00918     // poll the latched index pulse of the axis that was previously set up
00919 
00920     unsigned char byIRR, byAxisMask;
00921 
00922     byIRR = CurrentIRR();
00923     byAxisMask = (byIndexPollAxis & 1) ? LIXODD : LIXEVN;  // even or odd axis?
00924     if (byIRR & byAxisMask)                          // check latched index pulse
00925         return 1;
00926     return 0;
00927 
00928     //
00929     // a faster, but messier way
00930     //
00931     //fOutP(wBaseAddress + OCW3, 0x0a);           // IRR on next read
00932     //
00933     //return (   fInP(wBaseAddress + IRR)
00934     //         & ( (byIndexPollAxis & 1) ? LIXODD : LIXEVN ) // mask for even or odd
00935     //       );
00936 }

void Initialize unsigned short    wRequestedIrq
 

Definition at line 257 of file stgmembs.c.

Referenced by ServoToGoConstructor(), and stgMotInit().

00258 {
00259   /*
00260    * First find the the base I/O address of the board.
00261    *
00262    * only do this in the DOS example.  It's dangerous under 95, and can't be
00263    * done under NT
00264    */
00265    wBaseAddress = BaseFind();
00266    if (wBaseAddress == 0)
00267    {
00268        wNoBoardFlag = NO_BOARD;
00269    }
00270    wNoBoardFlag = BOARD_PRESENT;
00271 
00272   /*
00273    * Initialize the interrupt controller
00274    */
00275    if (wModel == MODEL1)
00276    {
00277    fOutP(wBaseAddress + MIO_2, 0x92);  // initialize INTC as output reg.
00278                                        // sets port D to input since we have
00279                                        // to set it to something.
00280    SetIrq(wRequestedIrq);              // selects the IRQ in INTC. Now, if a stray
00281                                        // interrupt is issued (see below) it will
00282                                        // go to an interrupt that isn't enabled on
00283                                        // the motherboard yet (if your system is
00284                                        // set up correctly).
00285    fOutP( wBaseAddress + ICW1, 0x1a ); // initialize 82C59 as single chip,
00286                                        // level triggered
00287    fOutP( wBaseAddress + ICW2, 0x00 ); // icw2 - not used, must write
00288                                        // could issue stray interrupt here - danger!
00289    fOutP( wBaseAddress + OCW1, 0xff);  // mask off all interrupt sources (the
00290                                        // interrupt on the motherboard isn't
00291                                        // enabled yet, you do that when you install
00292                                        // your interrupt handler.).
00293    }
00294    else   // must be a Model 2
00295    {
00296    fOutP(wBaseAddress + MIO_2, 0x8b);  // initialize CNTRL0 as output reg.
00297                                        // BRDTST to input.
00298                                        // sets port D, high and low, to input
00299                                        // since we have to set it to something.
00300    SetIrq(wRequestedIrq);              // selects the IRQ in CNTRL0. Now, if a stray
00301                                        // interrupt is issued (see below) it will
00302                                        // go to an interrupt that isn't enabled on
00303                                        // the motherboard yet (if your system is
00304                                        // set up correctly).
00305    }
00306 };

void MaskTimer2Interrupt void   
 

Definition at line 1615 of file stgmembs.c.

01616 {
01617     if (wNoBoardFlag == NO_BOARD)
01618     {
01619         return;
01620     }
01621 
01622     if (wModel == MODEL1)
01623         fOutP(wBaseAddress + OCW1, CurrentIRR() | TP2);
01624     else   // Model 2
01625         // we want to save the state of the slave mode, and set the
01626         // high nibble bits high, so you don't reset any latches.
01627         // bit pattern: 1111x000  where x is don't change
01628         fOutP(wBaseAddress + CNTRL1,
01629             (fInP(wBaseAddress + CNTRL1) & CNTRL1_NOT_SLAVE) | 0xf0);
01630 }

void MotSim void   
 

Definition at line 1291 of file stgmembs.c.

01292 {
01293     static long lState_1[MAX_AXIS] = {0};                    // state variables
01294     long lScaledUp;
01295     const short nScale = 10;
01296     int nAxis;
01297 
01298     for (nAxis = 0; nAxis < MAX_AXIS; nAxis++)
01299     {
01300         // The input is guaranteed to be +/- 12 bits
01301         // Scale up state so we don't loose resolution
01302         lScaledUp = lSimDac[nAxis] << nScale;
01303 
01304         // note: I assume right shift is sign preserving (for signed value)
01305 
01306         // lag
01307         lState_1[nAxis] += (lScaledUp - lState_1[nAxis]) >> (4 + nAxis); //lint !e704
01308                                                           //   ^^^^^^^ time constant
01309                                                           // is different for each axis
01310 
01311         // integrator (shift out the scale factor and then some)
01312         lSimEnc[nAxis] += lState_1[nAxis] >> (nScale + 1);               //lint !e704
01313     }
01314 }

short PollTimer2 void   
 

Definition at line 1578 of file stgmembs.c.

01579 {
01580     if (wNoBoardFlag == NO_BOARD)
01581     {
01582         return 0;
01583     }
01584 
01585     if (wModel == MODEL1)
01586         return !(CurrentIRR() & TP2);  // mask selects bit for TP2
01587     else   // MODEL 2
01588     {
01589         unsigned char byRegCntrl1, byNewCntrl1;
01590 
01591         byRegCntrl1 = fInP(wBaseAddress + CNTRL1);
01592         if (byRegCntrl1 & CNTRL1_INT_T2)
01593         {
01594             // If it's set, we want to reset the latch, by writing a zero
01595             // to CNTRL1_INT_T2.
01596 
01597             // When we write to CNTRL1, we don't want to change SLAVE, IEN_G2
01598             // IEN_T2, or IEN_T0 -- the lower 4 bits.  So, we start with
01599 
01600             byNewCntrl1 = byRegCntrl1 & 0x0f;     // (0000xxxx)
01601 
01602             // We don't want to reset WDTOUT, INT_G2, or INT_T0--we only want
01603             // to reset ...T2. (1101xxxx)
01604 
01605             byNewCntrl1 |= CNTRL1_WDTOUT | CNTRL1_INT_G2 | CNTRL1_INT_T0;
01606 
01607             fOutP(wBaseAddress + CNTRL1, byNewCntrl1);  // reset bit
01608 
01609             return 1;  // true
01610         }
01611     }
01612     return 0;      // false
01613 }

short PortBits2Index short    nPort
 

Definition at line 1112 of file stgmembs.c.

Referenced by DigitalOut1(), and DigitalOut2().

01113 {
01114     int nPortIndex = 9;
01115 
01116     switch(nPort)
01117     {
01118     case STG_PORT_A:
01119         nPortIndex = 0;
01120         break;
01121     case STG_PORT_B:
01122         nPortIndex = 1;
01123         break;
01124     case STG_PORT_C_LO:
01125     case STG_PORT_C_HI:
01126     case STG_PORT_C:
01127         nPortIndex = 2;
01128         break;
01129     case STG_PORT_D_LO:
01130     case STG_PORT_D_HI:
01131     case STG_PORT_D:
01132         nPortIndex = 3;
01133         break;
01134     }
01135     return nPortIndex;
01136 }

void RawDAC unsigned short    nAxis,
long    lCounts
 

Definition at line 678 of file stgmembs.c.

Referenced by ServoToGoDestructor(), ppmcDacWrite(), and stgDacWrite().

00679 {
00680     if (wNoBoardFlag == NO_BOARD)
00681     {
00682         return;
00683     }
00684 
00685     if ( nAxis > 7 )        // is axis within range?
00686        return;
00687 
00688     // input / output:
00689     //
00690     //    lCounts (decimal) ... -lCounts ... +0x1000 ... volts
00691     //
00692     //     0x1000  (4096)     0xfffff000           0       +10
00693     //          0                      0      0x1000         0
00694     // 0xfffff001 (-4095)          0xfff      0x1fff       -10
00695 
00696     // So, the domain might be different than you expected. I expected:
00697     //     0xf000 (-4096)  to  0xfff (4095), rather than
00698     //     0xf001 (-4095)  to 0x1000 (4096)
00699 
00700     // reverse slope so positive counts give positive voltage
00701     lCounts = - lCounts;
00702 
00703     // shift for DAC
00704     lCounts += 0x1000;
00705 
00706     if (lCounts > 0x1FFF)    // clamp + output
00707     {
00708         lCounts = 0x1FFF;
00709     }
00710     if (lCounts < 0)         // clamp - output
00711     {
00712         lCounts = 0;
00713     }
00714 
00715     if (wNoBoardFlag == NO_BOARD)      // are we simulating?
00716     {
00717         lSimDac[nAxis] = lCounts;
00718         return;
00719     }
00720 
00721 //    nCounts = (USHORT) (lCounts + 0x1000); // correct range for DAC
00722 
00723     fOutPW(wBaseAddress + DAC_0 + (nAxis << 1), (unsigned short)lCounts);
00724 };

unsigned long RawDIAll void   
 

Definition at line 953 of file stgmembs.c.

00954 {
00955     IO32 xInBits;
00956 
00957     if (wNoBoardFlag == NO_BOARD)
00958     {
00959         xInBits.all = 0;
00960         return(xInBits.all);
00961     }
00962 
00963     if (wModel == MODEL1)
00964     {
00965         xInBits.port.A = fInP(wBaseAddress + DIO_A);
00966         xInBits.port.B = fInP(wBaseAddress + DIO_B);
00967         xInBits.port.C = fInP(wBaseAddress + DIO_C);
00968         xInBits.port.D = fInP(wBaseAddress + DIO_D);
00969     }
00970     else  // Model 2
00971     {
00972         xInBits.port.A = fInP(wBaseAddress + PORT_A);
00973         xInBits.port.B = fInP(wBaseAddress + PORT_B);
00974         xInBits.port.C = fInP(wBaseAddress + PORT_C);
00975         xInBits.port.D = fInP(wBaseAddress + PORT_D);
00976     }
00977     return (xInBits.all);
00978 };

unsigned char RawDIBitPort unsigned char    byBitNumber,
short    nPort
 

Definition at line 980 of file stgmembs.c.

Referenced by stgDioCheck(), and stgDioRead().

00981 {
00982     unsigned char nData;
00983 
00984     if (nPort > 3)
00985         return 0;
00986     if (wModel == MODEL1)
00987         nData = fInP(wBaseAddress + aPortOffset_1[nPort]);
00988     else // Model 2
00989         nData = fInP(wBaseAddress + aPortOffset_2[nPort]);
00990     return nData & (1 << byBitNumber);
00991 }

unsigned char RawDIPort short    nPort
 

Definition at line 993 of file stgmembs.c.

Referenced by stgDioByteCheck(), stgDioByteRead(), stgDioShortRead(), and stgDioWordRead().

00994 {
00995     if (nPort > 3)
00996         return 0;
00997 
00998     if (wModel == MODEL1)
00999         return fInP(wBaseAddress + aPortOffset_1[nPort]);
01000     else
01001         return fInP(wBaseAddress + aPortOffset_2[nPort]);
01002 }

void RawDOAll unsigned long    lOutBits
 

Definition at line 1042 of file stgmembs.c.

Referenced by DioDirection2().

01043 {
01044     if (wNoBoardFlag == NO_BOARD)
01045     {
01046         return;
01047     }
01048     if (wModel == MODEL1)
01049     {
01050         fOutP(wBaseAddress + DIO_A, ((IO32 *)&lOutBits)->port.A);
01051         fOutP(wBaseAddress + DIO_B, ((IO32 *)&lOutBits)->port.B);
01052         fOutP(wBaseAddress + DIO_C, ((IO32 *)&lOutBits)->port.C);
01053         fOutP(wBaseAddress + DIO_D, ((IO32 *)&lOutBits)->port.D);
01054     }
01055     else  // Model 2
01056     {
01057         fOutP(wBaseAddress + PORT_A, ((IO32 *)&lOutBits)->port.A);
01058         fOutP(wBaseAddress + PORT_B, ((IO32 *)&lOutBits)->port.B);
01059         fOutP(wBaseAddress + PORT_C, ((IO32 *)&lOutBits)->port.C);
01060         fOutP(wBaseAddress + PORT_D, ((IO32 *)&lOutBits)->port.D);
01061     }
01062 };

void RawDOBitValPort unsigned char    byBitNumber,
unsigned char    bySet0or1,
unsigned short    nPort
 

Definition at line 1064 of file stgmembs.c.

Referenced by DigitalOut2(), stgAmpEnable(), and stgDioWrite().

01066 {
01067     unsigned nOffset;
01068     unsigned char byData;
01069 
01070     if (wNoBoardFlag == NO_BOARD)
01071     {
01072         return;
01073     }
01074 
01075     if (nPort > 3)
01076         return;
01077 
01078     if (wModel == MODEL1)
01079         nOffset = aPortOffset_1[nPort];
01080     else  // Model 2
01081         nOffset = aPortOffset_2[nPort];
01082 
01083     byData = fInP(wBaseAddress + nOffset);
01084     if (bySet0or1 == 1)
01085         byData |= 1 << byBitNumber;
01086     else
01087         byData &= ~(1u << byBitNumber);
01088     fOutP(wBaseAddress + nOffset, byData);
01089 };

void RawDOBytePort unsigned char    byData,
short    nPort
 

Definition at line 1091 of file stgmembs.c.

Referenced by DigitalOut1(), and stgDioByteWrite().

01092 {
01093     if (wNoBoardFlag == NO_BOARD)
01094     {
01095         return;
01096     }
01097 
01098     if (nPort > 3)
01099         return;
01100 
01101     if (wModel == MODEL1)
01102         fOutP(wBaseAddress + aPortOffset_1[nPort], byData);
01103     else  // Model 2
01104         fOutP(wBaseAddress + aPortOffset_2[nPort], byData);
01105 };

long ReadADC unsigned short    wAxis,
short *    counts_ptr
 

Definition at line 407 of file stgmembs.c.

00408 {
00409   short counts;
00410   if(counts_ptr == 0)
00411     {
00412       return 0;
00413     }
00414   counts = *counts_ptr;
00415     if (wNoBoardFlag == NO_BOARD)
00416     {
00417         return STG_SUCCESS;
00418     }
00419 
00420     if (wAxis > 7)
00421          return STG_FAILURE;
00422 
00423     if (wModel == MODEL1)
00424     {
00425         if ( !(CurrentIRR() & 0x08) ) // is the conversion done?
00426             return STG_FAILURE;                  // no, return failure
00427 
00428         // conversion is done, get counts.
00429 //        counts = fInPW(wBaseAddress + ADC_0 + (wAxis << 1));
00430 //        counts = fInPW(wBaseAddress + ADC_1);  // debug
00431     }
00432     else  // Model 2
00433     {
00434         // is the conversion done?
00435         if ( fInP(wBaseAddress + BRDTST) & BRDTST_EOC )
00436             return STG_FAILURE;                 // no, return failure
00437 
00438         // conversion is done, get counts.
00439 //        counts = fInPW(wBaseAddress + ADC_1);
00440     }
00441 
00442     counts = fInPW(wBaseAddress + ADC_0 + (wAxis << 1));
00443 
00444     if (counts & 0x1000)       // is sign bit negative?
00445         counts |= 0xf000;      // sign extend
00446     else
00447         counts &= 0xfff;       // make sure high order bits are zero.
00448 
00449     *counts_ptr = counts;
00450     return STG_SUCCESS;
00451 
00452 };

unsigned short ReadTimer2TerminalCount void   
 

Definition at line 1568 of file stgmembs.c.

01569 {
01570     unsigned short count;
01571     char *pByte = (char *)&count;
01572     fOutP(wBaseAddress + TMRCMD, 0x80);       // timer 2, latch
01573     *pByte++ = fInP(wBaseAddress + TIMER_2);  // LSB
01574     *pByte   = fInP(wBaseAddress + TIMER_2);  // MSB
01575     return count;
01576 }

void ResetIndexLatch void   
 

Definition at line 829 of file stgmembs.c.

00830 {
00831     // routine for Model 1
00832 
00833     fInP(wBaseAddress + ODDRST);        //lint !e534 reset index pulse latch for ODD axis
00834     fInP(wBaseAddress + BRDTST);        //lint !e534 reset index pulse latch for EVEN axis
00835 }

void ResetIndexLatches unsigned char    byLatchBits
 

Definition at line 837 of file stgmembs.c.

Referenced by stgEncoderResetIndex().

00838 {
00839     // routine for Model 2
00840     fOutP(wBaseAddress + IDL, byLatchBits);
00841 }

void ResetWatchdogLatch void   
 

Definition at line 1459 of file stgmembs.c.

01460 {
01461     unsigned char byCntrl1 = fInP(wBaseAddress + CNTRL1);
01462     byCntrl1 &= ~CNTRL1_WDTOUT;                   //set bit low, to reset
01463     // don't reset other latches
01464     byCntrl1 |= CNTRL1_INT_G2 | CNTRL1_INT_T2 | CNTRL1_INT_T0;
01465     fOutP(wBaseAddress + CNTRL1, byCntrl1);
01466 }

void SelectIndexAxis unsigned char    byAxis
 

Definition at line 849 of file stgmembs.c.

Referenced by stgEncoderReadLatch(), stgEncoderReadLevel(), and stgEncoderResetIndex().

00850 {
00851     // routine for Model 1
00852 
00853     // overloaded function.  Use this if you don't need to set polarity
00854 
00855     SelectIndexAxisWithPolarity(byAxis, byIndexPulsePolarity);
00856 }

void SelectIndexAxisWithPolarity unsigned char    byAxis,
unsigned char    byPol
 

Definition at line 858 of file stgmembs.c.

Referenced by SelectIndexAxis().

00859 {
00860     // routine for Model 1
00861 
00862     //
00863     // initialize stuff to poll index pulse
00864     //
00865     unsigned char byIntc;
00866 
00867     byIndexPollAxis = byAxis;           // save axis to check later
00868     byIndexPulsePolarity = byPol;       // save polarity as new default
00869     byAxis &= 0x6;                      // ignore low bit, we check 2 axes at a time
00870     byAxis <<= 3;                       // shift into position for IXS1, IXS0
00871     byIntc = fInP(wBaseAddress + INTC); // get a copy of INTC, we'll change
00872                                         // some bits in it, not all
00873     byIntc &= ~(IXLVL | IXS1 | IXS0);   // zero bits for axis and polarity
00874     byIntc |= byAxis;                   // put axes address in INTC
00875     if (byPol != 0)                     // is index pulse active high?
00876         byIntc |= IXLVL;
00877     fOutP(wBaseAddress + INTC, byIntc);
00878 
00879     //    ResetIndexLatch();
00880 
00881     // The latched index pulse should be low now.  If it's not, either something's
00882     // wrong, or we happened to initialize it while the index pulse was active.
00883 }

void SelectIndexOrExtLatch unsigned char    bySelectBits
 

Definition at line 885 of file stgmembs.c.

00886 {
00887     // routine for Model 2
00888 
00889     fOutP(wBaseAddress + SELDI, bySelectBits);
00890 }

void SelectInterruptPeriod long    lPeriodSelect
 

Definition at line 584 of file stgmembs.c.

Referenced by ServoToGoConstructor().

00585 {
00586    if (wNoBoardFlag == NO_BOARD)
00587    {
00588        return;
00589    }
00590 
00591    if (lPeriodSelect != MAX_PERIOD)
00592    {
00593        fOutP(wBaseAddress + TMRCMD, 0x56);   // timer 1, read/load LSB (MSB is 0)
00594                                              // mode 3 (square wave)
00595        fOutP(wBaseAddress + TIMER_1, 0xb4);  // 0xb4 = 180 -> 25 uSec period
00596    }
00597    else
00598    {
00599        fOutP(wBaseAddress + TMRCMD, 0x76);   // timer 1, read/load LSB then MSB
00600                                              // mode 3 (square wave)
00601        fOutP(wBaseAddress + TIMER_1, 0xff);  // LSB
00602        fOutP(wBaseAddress + TIMER_1, 0xff);  // MSB
00603    }
00604 
00605    switch (lPeriodSelect)
00606    {
00607         case _500_MICROSECONDS:
00608             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00609                                                    // MSB, mode 2 (real-time interrupt)
00610             fOutP(wBaseAddress + TIMER_0, 0x14);   // 0x14 = 20 = .5 mS
00611             fOutP(wBaseAddress + TIMER_0, 0x00);
00612             break;
00613         case _1_MILLISECOND:
00614             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00615                                                    // MSB, mode 2 (real-time interrupt)
00616             fOutP(wBaseAddress + TIMER_0, 0x28);   // 0x28 = 40 = 1 mS
00617             fOutP(wBaseAddress + TIMER_0, 0x00);
00618             break;
00619         case _2_MILLISECONDS:
00620             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00621                                                    // MSB, mode 2 (real-time interrupt)
00622             fOutP(wBaseAddress + TIMER_0, 0x50);   // 0x50 = 80 = 2 mS
00623             fOutP(wBaseAddress + TIMER_0, 0x00);
00624             break;
00625         case _3_MILLISECONDS:
00626             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00627                                                    // MSB, mode 2 (real-time interrupt)
00628             fOutP(wBaseAddress + TIMER_0, 0x78);   // 0x78 = 120 = 3 mS
00629             fOutP(wBaseAddress + TIMER_0, 0x00);
00630             break;
00631         case _4_MILLISECONDS:
00632             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00633                                                    // MSB, mode 2 (real-time interrupt)
00634             fOutP(wBaseAddress + TIMER_0, 0xA0);   // 0xA0 = 160 = 4 mS
00635             fOutP(wBaseAddress + TIMER_0, 0x00);
00636             break;
00637         case _5_MILLISECONDS:
00638             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00639                                                    // MSB, mode 2 (real-time interrupt)
00640             fOutP(wBaseAddress + TIMER_0, 0xC8);   // 0xC8 = 200 = 5 mS
00641             fOutP(wBaseAddress + TIMER_0, 0x00);
00642             break;
00643         case _10_MILLISECONDS:
00644             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00645                                                    // MSB, mode 2 (real-time interrupt)
00646             fOutP(wBaseAddress + TIMER_0, 0x90);   // 0x0190 = 400 = 10 mS
00647             fOutP(wBaseAddress + TIMER_0, 0x01);
00648             break;
00649         case _100_MILLISECONDS:
00650             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00651                                                    // MSB, mode 2 (real-time interrupt)
00652             fOutP(wBaseAddress + TIMER_0, 0xA0);   // 0x0FA0 = 4000 = 100 mS
00653             fOutP(wBaseAddress + TIMER_0, 0x0F);
00654             break;
00655         case _1_SECOND:
00656             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00657                                                    // MSB, mode 2 (real-time interrupt)
00658             fOutP(wBaseAddress + TIMER_0, 0x40);   // 0x9C40 = 40000 = 1 S
00659             fOutP(wBaseAddress + TIMER_0, 0x9c);
00660             break;
00661         case MAX_PERIOD:
00662             fOutP(wBaseAddress + TMRCMD, 0x34);    // timer 0, read/load LSB followed by
00663                                                    // MSB, mode 2 (real-time interrupt)
00664             fOutP(wBaseAddress + TIMER_0, 0xff);   // LSB
00665             fOutP(wBaseAddress + TIMER_0, 0xff);   // MSB
00666             break;
00667         default:
00668             // wrong input? then don't change it
00669             break;
00670    }
00671 };

void ServoToGoConstructor unsigned short    wRequestedIrq
 

Definition at line 97 of file stgmembs.c.

Referenced by __attribute__(), and stgMotInit().

00098 {
00099 #if defined ( STG_LINUX )
00100     iopl(3);  // get access to I/O ports, must be root.
00101 #endif
00102     wNoBoardFlag = NO_BOARD;
00103     Initialize(wRequestedIrq);   // figure out board address, init irq controller
00104     EncoderInit();
00105     SelectInterruptPeriod(_1_MILLISECOND);  // initialize timer
00106     byIndexPulsePolarity = 1;               // default active level high
00107     if (wModel == MODEL2)
00108         fOutP(wBaseAddress + CNTRL1, CNTRL1_NOT_SLAVE);
00109 };

void ServoToGoDestructor void   
 

Definition at line 117 of file stgmembs.c.

00118 {
00119   unsigned short nAxis;
00120     StopInterrupts();
00121 
00122     // set all the DAC outputs to 0.
00123     for (nAxis = 0; nAxis < MAX_AXIS; nAxis++)
00124         RawDAC(nAxis, 0);
00125 
00126     // set all the digital I/O bits to input
00127     DioDirection2(0);
00128 }

void SetDDir unsigned short    nSwDir
 

Definition at line 1228 of file stgmembs.c.

Referenced by DioDirection(), and DioDirection2().

01229 {
01230     unsigned char byHwDir;                   // direction bits for hardware
01231     unsigned char bySaveReg, bySaveIMR, bySaveCntrl1, bySaveCntrl0;
01232 
01233     if (wModel == MODEL1)
01234     {
01235         bySaveReg = fInP(wBaseAddress + INTC);   // INTC needs to be saved, because
01236                                                  // MIO_2 reinitializes the 8255 which
01237                                                  // implements the INTC register.
01238         byHwDir = 0x92;                          // initialize port D input
01239         if (nSwDir & STG_PORT_D)                 // is port D output?
01240              byHwDir &= ~D_DIR_BIT;              // if yes, set bit to 0,
01241         bySaveIMR = fInP(wBaseAddress + IMR);    // get the current interrupt mask
01242         fOutP(wBaseAddress + OCW1, 0xff);        // mask off all interrupts
01243         fOutP(wBaseAddress + MIO_2, byHwDir);    // set direction for port D
01244         fOutP(wBaseAddress + INTC, bySaveReg);   // restore interrupt control reg.
01245         fOutP(wBaseAddress + OCW1, bySaveIMR);   // restore interrupt mask
01246     }
01247     else  // Model 2
01248     {
01249         bySaveCntrl0 = fInP(wBaseAddress + CNTRL0); // CNTRL0 needs to be saved, because
01250                                                  // D_DIR reinitializes the 8255 which
01251                                                  // implements the CNTRL0 register.
01252         byHwDir = 0x8b;                          // initialize CNTRL0 as output reg.
01253                                                  // BRDTST to input.
01254                                                  // sets port D, high and low, to input
01255         if (nSwDir & STG_PORT_D_LO)              // low nibble
01256             byHwDir &= ~D_LOW_DIR_BIT;
01257         if (nSwDir & STG_PORT_D_HI)              // high nibble
01258             byHwDir &= ~D_HI_DIR_BIT;
01259 
01260         bySaveCntrl1 = fInP(wBaseAddress+CNTRL1);// save for interrupt enables
01261 
01262             // don't reset any latches; put in slave state;
01263             // disable interrupts, so the glitch in CTRL0 doesn't
01264             // cause an interrupt on wrong irq
01265         fOutP(wBaseAddress + CNTRL1, 0xf0);
01266 
01267         fOutP(wBaseAddress + D_DIR, byHwDir);    // set port D direction
01268 
01269             // restore CNTRL0, because it was re-initialized, which
01270             // lost any previous contents.
01271         fOutP(wBaseAddress + CNTRL0, bySaveCntrl0);
01272 
01273             // re-enable interrupts, and restore slave state, don't
01274             // reset any latches. (1111xxxx)
01275         fOutP(wBaseAddress+CNTRL1, (bySaveCntrl1 & 0x0f) | 0xf0);
01276     }
01277 };

void SetEncoderCounts unsigned short    nAxis,
long    lCounts
 

Definition at line 1357 of file stgmembs.c.

01358 {
01359     unsigned short wAddress;
01360     char *ByteUnion = (char *)&lCounts;  // get pointer to lCounts, so you
01361                                          // can take it apart byte by byte
01362 
01363     wAddress = wBaseAddress + CNT0_D;
01364     wAddress += (nAxis & 0x6) << 1; // shift to multiply by 2
01365                                     // pairs of data regs seperated by pairs
01366                                     // of control regs, skip over control.
01367     wAddress += nAxis & 1;
01368     fOutP(wAddress, ByteUnion[0]);
01369     fOutP(wAddress, ByteUnion[1]);
01370     fOutP(wAddress, ByteUnion[2]);
01371 
01372     // transfer the preset register to the count register
01373     fOutP(wAddress + 2, 0x09);
01374 
01375     // set things for the part that extends the 24 bit counter
01376     // to 32 bits.
01377     byEncHighByte[nAxis] = ByteUnion[3];
01378     byOldByte2[nAxis] = ByteUnion[2];
01379 }

void SetIrq unsigned short    wRequestedIrq
 

Definition at line 135 of file stgmembs.c.

Referenced by Initialize().

00136 {
00137     unsigned char byIntReg;
00138 
00139     if (wNoBoardFlag == NO_BOARD)
00140         return;
00141 
00142     wIrq = wRequestedIrq;  // assume it's OK for now, check later
00143 
00144     if (wModel == MODEL1)
00145         byIntReg = 0x80;       // initial value for the high bits in the register
00146                                // sets auto zero off
00147     else   // MODEL2
00148         byIntReg = 0x88;       // cal high too, not calibrating ADC
00149 
00150     // now put low bits into byIntReg to select irq
00151 
00152     switch (wRequestedIrq)
00153     {
00154         case 3: break;      // add zero
00155 
00156         case 5: byIntReg |= 4;
00157                 break;
00158 
00159         case 7: byIntReg |= 2;
00160                 break;
00161 
00162         case 9: byIntReg |= 6;
00163                 break;
00164 
00165         case 10: byIntReg |= 5;
00166                  break;
00167 
00168         case 11: byIntReg |= 7;
00169                  break;
00170 
00171         case 12: byIntReg |= 3;
00172                  break;
00173 
00174         case 15: byIntReg |= 1;
00175                  break;
00176 
00177         default: wIrq = 5;      // ERROR, requested irq not valid, use 5
00178                  byIntReg |= 4; // There is no safe value, leaving zero
00179                                 // here would select IRQ 3 which is worse
00180                                 // than 5 because IRQ 3 is usually for COM 2
00181                  break;
00182     }
00183 
00184     if (wModel == MODEL1)
00185         fOutP(wBaseAddress + INTC, byIntReg);  // set irq
00186     else   // MODEL2
00187         fOutP(wBaseAddress + CNTRL0, byIntReg);
00188 }

short SpinReadADC unsigned short    wAxis
 

Definition at line 366 of file stgmembs.c.

Referenced by stgAdcRead().

00367 {
00368     short counts;
00369     short j;
00370 
00371     if (wNoBoardFlag == NO_BOARD)
00372     {
00373         return 0;
00374     }
00375 
00376     if (wAxis > 7)
00377          return -1;
00378 
00379     if (wModel == MODEL1)
00380     {
00381         // make sure conversion is done, assume polling delay is done.
00382         // EOC (End Of Conversion) is bit 0x08 in IIR (Interrupt Request
00383         // Register) of Interrupt Controller.  Don't wait forever though
00384         // bail out eventually.
00385 
00386         for ( j = 0; (!(CurrentIRR() & 0x08)) && (j < 10000); j++);
00387 
00388         counts = ( fInPW(wBaseAddress + ADC_0 + (wAxis << 1)) );
00389     }
00390     else
00391     {
00392         // is the conversion done?
00393         for ( j = 0; (fInP(wBaseAddress + BRDTST) & BRDTST_EOC) && (j < 10000); j++);
00394 
00395         // conversion is done, get counts.
00396         counts = fInPW(wBaseAddress + ADC);
00397     }
00398 
00399     if (counts & 0x1000)       // is sign bit negative?
00400         counts |= 0xf000;      // sign extend
00401     else
00402         counts &= 0xfff;       // make sure high order bits are zero.
00403 
00404     return counts;
00405 };

void StartADC unsigned short    wAxis
 

Definition at line 313 of file stgmembs.c.

Referenced by stgAdcStart(), and stgAioRead().

00314 {
00315     if (wNoBoardFlag == NO_BOARD)
00316     {
00317         return;
00318     }
00319 
00320     if (wAxis > 7)
00321         return;
00322 
00323     if (wModel == MODEL1)
00324     {
00325         // do a dummy read from the ADC, just to set the input multiplexer to
00326         // the right channel
00327         fInPW(wBaseAddress + ADC_0 + (wAxis << 1));        //lint !e534
00328 
00329         // wait 4 uS for settling time on the multiplexer and ADC
00330         // you probably shouldn't really have a delay in
00331         // a driver.
00332         Timer2Delay(28);
00333 
00334         // now start conversion.
00335         fOutPW(wBaseAddress + ADC_0 + (wAxis << 1), 0);
00336     }
00337     else  // Model 2
00338     {
00339         unsigned char Cntrl0;
00340 
00341         Cntrl0 = fInP(wBaseAddress + CNTRL0) & 0x07;  // save irq
00342 
00343         Cntrl0 |= (wAxis << 4) | 0x88;  // shift bits to AD2, AD1, AD0
00344                                         // set bit 0x80 high for autozero
00345                                         // set bit 0x08 high, not calibrating
00346         fOutP(wBaseAddress + CNTRL0, Cntrl0);  // select ADC channel
00347 
00348         // don't have to do a dummy read for a model 2
00349 
00350         // wait 4 uS for settling time on the multiplexer and ADC
00351         // you probably shouldn't really have a delay in
00352         // a driver.
00353         Timer2Delay(28);
00354 
00355         // now start conversion.
00356         fOutPW(wBaseAddress + ADC, 0);
00357 
00358     }
00359 };

void StartInterrupts void   
 

Definition at line 1651 of file stgmembs.c.

01652 {
01653     if (wNoBoardFlag == NO_BOARD)
01654     {
01655         return;
01656     }
01657     if (wModel == MODEL1)
01658         fOutP(wBaseAddress + OCW1, ~0x04);   // enable interrupt for timer 0
01659     else  // MODEL2
01660         // we want to save the state of the slave mode, and set the
01661         // high nibble bits high, so you don't reset any latches.
01662         // 1111x001, where x means don't change
01663     {
01664         fOutP(wBaseAddress + CNTRL1, CNTRL1_IEN_T0 | CNTRL1_NOT_SLAVE);
01665     }
01666 };

void StartTimer2RTI unsigned short    count
 

Definition at line 1553 of file stgmembs.c.

01554 {
01555   char *pByte;
01556    if (wNoBoardFlag == NO_BOARD)
01557    {
01558        return;
01559    }
01560 
01561    pByte = (char *)&count;
01562    fOutP(wBaseAddress + TMRCMD, 0xb4);       // timer 2, read/load LSB followed
01563                                              // by MSB, mode 2 (real time int).
01564    fOutP(wBaseAddress + TIMER_2, *pByte++);  // LSB (little endian)
01565    fOutP(wBaseAddress + TIMER_2, *pByte);    // MSB
01566 }

void StartTimer2TerminalCount unsigned short    count
 

Definition at line 1538 of file stgmembs.c.

Referenced by Timer2Delay().

01539 {
01540   char *pByte;
01541    if (wNoBoardFlag == NO_BOARD)
01542    {
01543        return;
01544    }
01545 
01546    pByte = (char *)&count;
01547    fOutP(wBaseAddress + TMRCMD, 0xb0);       // timer 2, read/load LSB followed
01548                                              // by MSB, mode 0 (terminal count)
01549    fOutP(wBaseAddress + TIMER_2, *pByte++);  // LSB (little endian)
01550    fOutP(wBaseAddress + TIMER_2, *pByte);    // MSB
01551 }

void StopInterrupts void   
 

Definition at line 1673 of file stgmembs.c.

01674 {
01675     if (wNoBoardFlag == NO_BOARD)
01676     {
01677         return;
01678     }
01679     if (wModel == MODEL1)
01680         fOutP(wBaseAddress + OCW1, 0xff);     // disable all interrupts
01681     else  // MODEL2
01682         // we want to save the state of the slave mode, and set the
01683         // high nibble bits high, so you don't reset any latches.
01684         // disable all interrupts, since only one can be enabled at
01685         // a time (currently).  If more than one was enabled, it's
01686         // an error (currently).
01687         // 1111x000, where x means not changed.
01688         fOutP(wBaseAddress + CNTRL1,
01689             (fInP(wBaseAddress + CNTRL1) & CNTRL1_NOT_SLAVE) | 0xf0);
01690 };

void StopTimer void   
 

Definition at line 1506 of file stgmembs.c.

01507 {
01508     if (wNoBoardFlag == NO_BOARD)
01509     {
01510         return;
01511     }
01512 
01513     // stop the timer by putting it into one shot mode, it will never get
01514     // a trigger
01515 
01516     // bug bug this doesn't work
01517 
01518     fOutP(wBaseAddress + TMRCMD, 0x0a);    // timer 0, mode 1
01519 }

void Timer2Delay unsigned short    counts
 

Definition at line 1526 of file stgmembs.c.

Referenced by StartADC().

01527 {
01528     if (wNoBoardFlag == NO_BOARD)
01529     {
01530         return;
01531     }
01532 
01533     StartTimer2TerminalCount(counts);
01534 
01535     while (PollTimer2());
01536 }

void UnMaskTimer2Interrupt void   
 

Definition at line 1632 of file stgmembs.c.

01633 {
01634     if (wModel == MODEL1)
01635         fOutP(wBaseAddress + OCW1, CurrentIRR() & ~TP2);
01636     else   // Model 2
01637     {
01638         // we want to save the state of the slave mode, and set the
01639         // high nibble bits high, so you don't reset any latches.
01640         // bit pattern: 1111x010 where x is don't change
01641         fOutP(wBaseAddress + CNTRL1,
01642             (fInP(wBaseAddress + CNTRL1) & CNTRL1_NOT_SLAVE) | CNTRL1_IEN_T2);
01643     }
01644 }

char __attribute__ (unused)    [static]
 

Definition at line 31 of file stgmembs.c.

00031                                                   : stgmembs.c,v 1.5 2001/11/05 16:59:55 wshackle Exp $";
00032 
00033 
00034 #include "locdefs.h"
00035 #define assert(a)
00036 
00037 #include "offsets.h"
00038 #include "stgdefs.h"
00039 #include "locsysio.h"
00040 
00041 
00042 inline void fOutP(unsigned short port, unsigned char data)
00043 {
00044   outb(data, port);
00045 }

unsigned char fInP unsigned short    port [inline]
 

Definition at line 52 of file stgmembs.c.

00053 {
00054   return inb(port);
00055 }

unsigned short fInPW unsigned short    port [inline]
 

Definition at line 57 of file stgmembs.c.

00058 {
00059   return inw(port);
00060 }

void fOutPW unsigned short    port,
unsigned short    data
[inline]
 

Definition at line 47 of file stgmembs.c.

00048 {
00049   outw(data, port);
00050 }


Variable Documentation

const int aPortOffset_1[] = {DIO_A, DIO_B, DIO_C, DIO_D} [static]
 

Definition at line 73 of file stgmembs.c.

const int aPortOffset_2[] = {PORT_A, PORT_B, PORT_C, PORT_D} [static]
 

Definition at line 74 of file stgmembs.c.

unsigned char byEncHighByte[MAX_AXIS] [static]
 

Definition at line 76 of file stgmembs.c.

unsigned char byIndexPollAxis [static]
 

Definition at line 68 of file stgmembs.c.

unsigned char byIndexPulsePolarity [static]
 

Definition at line 69 of file stgmembs.c.

unsigned char byOldByte2[MAX_AXIS] [static]
 

Definition at line 77 of file stgmembs.c.

long lSimDac[MAX_AXIS] [static]
 

Definition at line 70 of file stgmembs.c.

long lSimEnc[MAX_AXIS] [static]
 

Definition at line 71 of file stgmembs.c.

unsigned short wAxesInSys [static]
 

Definition at line 66 of file stgmembs.c.

unsigned short wBaseAddress [static]
 

Definition at line 62 of file stgmembs.c.

unsigned short wIrq [static]
 

Definition at line 63 of file stgmembs.c.

unsigned short wModel [static]
 

Definition at line 64 of file stgmembs.c.

unsigned short wNoBoardFlag [static]
 

Definition at line 65 of file stgmembs.c.

unsigned short wSaveDirs [static]
 

Definition at line 67 of file stgmembs.c.


Generated on Sun Dec 2 15:28:32 2001 for EMC by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001