PC7166Card.hpp

//=============================================================================
//  Unified IO - C++ interface for industrial IO cards
//  Copyright (C) 2000, UAB "BBD SOFT" ( http://www.bbdsoft.com/ )
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted 
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
//=============================================================================


#ifndef _PC7166CARD_
#define _PC7166CARD_

#ifndef _IOCARD_
   #include "iocard.hpp"
#endif

#ifndef _UNIIO_H
   #include "uniio.h"
#endif


//-----------------------------------------------------------------------------
namespace Uniio
{

class _Export_UNIIO PC7166Card : public IOCard
{

   typedef IOCard Inherited;

public:

   PC7166Card ( const unsigned inBaseIOPort );
   virtual ~PC7166Card ();

   unsigned baseIOPort () const;

   virtual IOCard & reset ();

protected:

   enum PC7166Constants
   {
      maxEncoders = 4
   };

   enum Commands
   {
       cmMasterReset = 0x20
     , cmInputSetup = 0x68
     , cmAddrReset = 0x01
     , cmLatchCounter = 0x02
     , cmResetCounter = 0x04
     , cmPresetCounter = 0x08
   };

   enum QuadratureMultiplier
   {
       qmX1 = 0xC1
     , qmX2 = 0xC2
     , qmX4 = 0xC3
   };

   virtual IOCard & updateInputs ( const IOTrack & inTrack
                                 , long * inImage
                                 , long & inTrackState
                                 );

   virtual IOCard & updateOutputs ( const IOTrack & inTrack
                                  , const long * const inImage
                                  , long & inTrackState
                                  );

   virtual IOCard & addTrack ( IOTrack & inTrack ) ;

private:

   const unsigned theBaseIOPort; 
   long thePreviousValues[maxEncoders];

}; // end PC7166Card class declaration

#include "pc7166card.inl"

}; // end namespace

#endif

PC7166Card.inl

//=============================================================================
//  Unified IO - C++ interface for industrial IO cards
//  Copyright (C) 2000, UAB "BBD SOFT" ( http://www.bbdsoft.com/ )
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted 
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
//=============================================================================


#ifndef _PC7166CARD_INL
#define _PC7166CARD_INL

#ifndef _BTRACE_
   #include "btrace.hpp"
#endif

//-----------------------------------------------------------------------------
inline unsigned PC7166Card::baseIOPort () const
{
BFUNCTRACE_ALL ();

return theBaseIOPort;
} // end PC7166Card::baseIOPort () const

#endif

PC7166Card.cpp

//=============================================================================
//  Unified IO - C++ interface for industrial IO cards
//  Copyright (C) 2000, UAB "BBD SOFT" ( http://www.bbdsoft.com/ )
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted 
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
//=============================================================================


#ifndef _BTRACE_
   #include "btrace.hpp"
#endif

#ifndef _CSTDLIB_
   #include 
#endif

#ifndef _PC7166CARD_
   #include "pc7166card.hpp"
#endif

#ifndef _STDEXCEPT_
   #include 
#endif

#ifndef _IOPORT_
   #include "ioport.hpp"
#endif

#ifndef _IOTRACK_
   #include "iotrack.hpp"
#endif

#ifndef _IOSTREAM_
   #include 
#endif

using namespace std;
using namespace Uniio;

//-----------------------------------------------------------------------------
PC7166Card::PC7166Card ( const unsigned inBaseIOPort )
  : IOCard ("PC7166")
  , theBaseIOPort ( inBaseIOPort )
{
BFUNCTRACE_DEVELOP ();

if (   theBaseIOPort != 0x220
    && theBaseIOPort != 0x240
    && theBaseIOPort != 0x250
    && theBaseIOPort != 0x260
    && theBaseIOPort != 0x300
    && theBaseIOPort != 0x310
    && theBaseIOPort != 0x330
    && theBaseIOPort != 0x340
    && theBaseIOPort != 0x350
    && theBaseIOPort != 0x360
   )
{
   throw logic_error ("PC7166 card: invalid base IO port number specified.");
} // endif 


// initialize previous values array to not 0, so that addTrack () could check for 
// duplicated encoders.
for (int i=0; i 0)
      {
         // this means we have forward movement or movement backward with rollover
         if (abs(difference) > 0x007FFFFF)
         {
            // this means we have backward rollover
            thePreviousValues[i] -= 0x01000000;
         }
      }
      else
      {
         // we have move backward or forward rollover
         if (abs(difference) > 0x007FFFFF)
         {
            // this means we have Forward rollover
            thePreviousValues[i] += 0x01000000;
         }
      }

      position += thePreviousValues[i] & 0xff000000;
      
      inImage[ i - inTrack.startingPoint() ] = position;
      thePreviousValues[i] = position;
   } // endif
} // endfor
return * this;
} // end PC7166Card::updateInputs (..)


//-----------------------------------------------------------------------------
IOCard & PC7166Card::updateOutputs ( const IOTrack & inTrack
                                   , const long *  const inImage
                                   , long & inTrackState
                                   )
{
BFUNCTRACE_DEVELOP ();

for (int i = inTrack.startingPoint(); i < inTrack.numberOfPoints() ; i++)
{
   if ( inTrack.pointType (i) != IOTrack::notUsed)
   {
      long currentValue = inImage[ i - inTrack.startingPoint () ];

      // this card supports preseting encoder counter to certain value
      // but we should only do that if user intensionally modified
      // the counter value.
      if (currentValue != thePreviousValues[i])
      {
         thePreviousValues [i] = currentValue;

         if (inTrack.pointType ( i - inTrack.startingPoint () ) == IOTrack::reverseCounter)
         {
            currentValue = 0x00ffffff - (currentValue & 0x00ffffff);
         } // endif

         unsigned char (&byteArray)[4] = (unsigned char(&)[4])currentValue;
         IOPort controlPort ( baseIOPort() + i*2 + 1 );
         IOPort dataPort ( baseIOPort() + i*2 );

         controlPort.writeChar ( cmAddrReset);
         dataPort.writeChar ( byteArray[0] );
         dataPort.writeChar ( byteArray[1] );
         dataPort.writeChar ( byteArray[2] );
         controlPort.writeChar ( cmPresetCounter );
      } // endif
   } // endif
} // endfor

return * this;
} // end PC7166Card::updateOutputs (..)


//-----------------------------------------------------------------------------
IOCard & PC7166Card::addTrack ( IOTrack & inTrack )
{
BFUNCTRACE_DEVELOP ();

if (inTrack.numberOfPoints()+inTrack.startingPoint() > maxEncoders)
{
   throw logic_error ("PC7166 only supports up to 4 encoders");
} // endif

for ( int i = inTrack.startingPoint()
    ; i < inTrack.numberOfPoints()
    ; i++)
{
   if (   inTrack.pointType ( i - inTrack.startingPoint()) != IOTrack::counter
       && inTrack.pointType ( i - inTrack.startingPoint()) != IOTrack::reverseCounter
       && inTrack.pointType ( i - inTrack.startingPoint()) != IOTrack::notUsed
      )
   {
      throw logic_error ("PC7166 point type can only be Counter or Reverse Counter.");
   } // endif

   if ( inTrack.pointType (i-inTrack.startingPoint()) != IOTrack::notUsed)
   {
      if (thePreviousValues[i] != 0xffffffff)
      {
         throw logic_error ("PC7166: encoder is already used in another track.");
      } // endif

      IOPort controlPort ( baseIOPort() + i*2 + 1 );
      controlPort.writeChar ( cmMasterReset );
      controlPort.writeChar ( cmInputSetup );
      controlPort.writeChar ( qmX4 );
      controlPort.writeChar ( cmResetCounter );

      unsigned long currentValue = 0;
      unsigned char (&byteArray)[4] = (unsigned char(&)[4])currentValue;
      controlPort.writeChar ( cmAddrReset);
      IOPort dataPort ( baseIOPort() + i*2 );
      dataPort.writeChar ( byteArray[0] );
      dataPort.writeChar ( byteArray[1] );
      dataPort.writeChar ( byteArray[2] );
      controlPort.writeChar ( cmPresetCounter );
      thePreviousValues [i] = 0;

   } // endif
} // endfor

return * this;
} // end PC7166Card::addTrack (..)


//-----------------------------------------------------------------------------
IOCard & PC7166Card::reset ()
{
BFUNCTRACE_DEVELOP ();

// reset all 4 counters to 0
for ( int i = 0 ; i < maxEncoders ; i++ )
{
   IOPort controlPort ( baseIOPort() + i*2 + 1 );
   controlPort.writeChar ( cmMasterReset );
   controlPort.writeChar ( cmInputSetup );
   controlPort.writeChar ( qmX4 );
   controlPort.writeChar ( cmResetCounter );
   thePreviousValues [i] = 0;
} // endfor

return * this;
} // end PC7166Card::reset ()

Back to US Digital PC7166 card description
Back to Unified IO description

Copyright © 2000 UAB "BBD SOFT"
All Rights Reserved.
All brand names and products names are trademarks or registered trademarks of their respective companies.