00001 #ifndef ETHERCATENCODER_HPP
00002 #define ETHERCATENCODER_HPP
00003
00004 #include "rtt/dev/EncoderInterface.hpp"
00005 #include <rtt/DataObjectInterfaces.hpp>
00006
00007 namespace RTT
00008 {
00012 class EtherCATEncoder
00013 : public EncoderInterface
00014 {
00015 struct SetPosInfo {
00016 unsigned int setpos;
00017 bool setposreq;
00018 };
00019 struct PosInfo {
00020 int pos;
00021 bool upcounting;
00022 int turn;
00023 };
00024 DataObjectLockFree<PosInfo> mPosLF;
00025 DataObjectLockFree<SetPosInfo> mSetPosInfoLF;
00026 unsigned int mresolution;
00027 unsigned char* mstartaddressin;
00028 unsigned char* mstartaddressout;
00029 unsigned char prevoverfl;
00030 unsigned char prevunderfl;
00031 public:
00032
00033
00034
00035 EtherCATEncoder(unsigned char* startaddressinput, unsigned char* startaddressoutput, unsigned int resolution = 65536, bool upcounting = true)
00036 : mPosLF( "Pos" ),
00037 mSetPosInfoLF( "PosInfo" ),
00038 mresolution(resolution),
00039 mstartaddressin(startaddressinput),
00040 mstartaddressout(startaddressoutput),
00041 prevoverfl(0),
00042 prevunderfl(0)
00043 {
00044
00045 SetPosInfo setposinit;
00046 setposinit.setpos = 0; setposinit.setposreq = false;
00047 mSetPosInfoLF.Set(setposinit);
00048
00049
00050 PosInfo posinit;
00051 posinit.pos = 0; posinit.upcounting = upcounting; posinit.turn = 0;
00052 mPosLF.Set(posinit);
00053 }
00054 virtual ~EtherCATEncoder() {}
00055
00056 void update()
00057 {
00058 PosInfo postmp;
00059 SetPosInfo setpostmp;
00060 mPosLF.Get( postmp );
00061 mSetPosInfoLF.Get( setpostmp );
00062
00063 int prevpos = postmp.pos;
00064 int prevturn = postmp.turn;
00065
00066
00067 unsigned char status = mstartaddressin[0];
00068 if( (prevoverfl == 0) && ((status>>4 & 1) == 1) )
00069 postmp.turn++;
00070 else if( (prevunderfl == 0) && ((status>>3 & 1) == 1) )
00071 postmp.turn--;
00072 prevoverfl = status>>4 & 1;
00073 prevunderfl = status>>3 & 1;
00074
00075 if(!setpostmp.setposreq) {
00076 mstartaddressout[0] = mstartaddressout[0] & 0xfb;
00077
00078
00079 postmp.pos = mstartaddressin[2];
00080 postmp.pos = postmp.pos<<8;
00081 postmp.pos = postmp.pos | mstartaddressin[1];
00082 }
00083 else {
00084 mstartaddressout[1] = setpostmp.setpos;
00085 mstartaddressout[2] = setpostmp.setpos>>8;
00086 mstartaddressout[0] = mstartaddressout[0] | 0x04;
00087 setpostmp.setposreq = false;
00088 }
00089
00090
00091 if(prevturn > postmp.turn)
00092 postmp.upcounting = false;
00093 else if(prevturn < postmp.turn)
00094 postmp.upcounting = true;
00095 else if(prevpos > postmp.pos)
00096 postmp.upcounting = false;
00097 else if(prevpos < postmp.pos)
00098 postmp.upcounting = true;
00099
00100 mPosLF.Set( postmp );
00101 mSetPosInfoLF.Set( setpostmp );
00102 }
00103
00107 virtual int positionGet() const {
00108 return mPosLF.Get().pos;
00109 }
00110
00114 virtual int turnGet() const {
00115 return mPosLF.Get().turn;
00116 }
00117
00121 virtual void positionSet( int pos) {
00122 SetPosInfo settmp;
00123 settmp.setpos = pos;
00124 settmp.setposreq = true;
00125 mSetPosInfoLF.Set(settmp);
00126 }
00127
00131 virtual void turnSet( int t ) {
00132 PosInfo tmp;
00133 mPosLF.Get(tmp);
00134 tmp.turn = t;
00135 mPosLF.Set(tmp);
00136 }
00137
00143 virtual int resolution() const { return mresolution; }
00144
00151 virtual bool upcounting() const {
00152 return mPosLF.Get().upcounting;
00153 }
00154 };
00155 }
00156
00157 #endif