]> rtime.felk.cvut.cz Git - mf6xx.git/blobdiff - src/HuLinux-2.4.3/PCT7303B.c
Initial commit; HuLinux ver. 2.4.3; All files auto-indented
[mf6xx.git] / src / HuLinux-2.4.3 / PCT7303B.c
diff --git a/src/HuLinux-2.4.3/PCT7303B.c b/src/HuLinux-2.4.3/PCT7303B.c
new file mode 100644 (file)
index 0000000..66671ab
--- /dev/null
@@ -0,0 +1,577 @@
+/****************************************************************/\r
+/**@file PCT7303B.c:\r
+ * Description: API layer for TEDIA PCT-7303B card.             *\r
+ * Dependency: Windows 32, Windows 64 or Linux                  *\r
+ *                Copyright 2010 Jaroslav Fojtik                *\r
+ ****************************************************************/\r
+\r
+#if defined(_WIN32) || defined(_WIN64)\r
+#include <windows.h>\r
+#else\r
+#include <sys/io.h>\r
+#endif\r
+#include <malloc.h>\r
+#include <math.h>\r
+\r
+#include "hudaqlib.h"\r
+#include "hudaq_internal.h"\r
+\r
+\r
+#define DI_CHANNELS   1                ///< Amount of Digital Outputs\r
+#define DO_CHANNELS   1                ///< Amount of Digital Inputs\r
+#define DA_CHANNELS   0                ///< Amount of Analog Outputs\r
+#define AD_CHANNELS   0                ///< Amount of Analog Inputs\r
+#define ENC_CHANNELS  3                ///< Amount of Encoders\r
+#define CTR_CHANNELS  1                ///< Amount of counters\r
+#define STEP_CHANNELS 0                ///< Amount of steppers\r
+\r
+\r
+#define MASTERFREQUENCY 1000   ///< Internal oscillator frequency is 1kHz\r
+\r
+#define IrcResetCounter 2      ///< Binary flag for IrcOptions\r
+\r
+\r
+/** Cache of PCT-7303B state */\r
+typedef struct\r
+{\r
+       UserDataHeader Hdr;                   ///< General device setup\r
+\r
+       int EncOptions[ENC_CHANNELS];           ///< Bit options for encoders\r
+\r
+       unsigned __int8 DOReg;          ///< Port configuration register\r
+       unsigned __int8 IRQCfgReg;\r
+       unsigned __int8 INTEnReg;\r
+       unsigned __int8 TimerReg;\r
+       unsigned __int8 CNTEnReg;\r
+} PCT_7303B_Private;\r
+\r
+\r
+/** Symbolic aliases for available registers inside BADR1 read. */\r
+typedef enum\r
+{\r
+       DINReg     = 0,         // RD only\r
+       DOUTReg    = 4,         // WR only\r
+\r
+       IRQCfgReg  = 0x180,             // WR only\r
+       IRQStatusReg = 0x180,           // RD only\r
+       IRQClrReg =  0x184,             // WR only\r
+\r
+       TimerReg =  0x3F0,              // RW\r
+       INTEnReg =  0x18C,              // WR only\r
+\r
+       CNT0SetReg = 0x200,             // RW\r
+       CNT1SetReg = 0x204,             // RW\r
+       CNT2SetReg = 0x208,             // RW\r
+\r
+       CNTEnReg = 0x380,               // WR only\r
+       CNTCtrReg= 0x384,               // WR only\r
+\r
+} MEM_BAR1;    // Memory space #0 on F1\r
+\r
+\r
+/** write to memory mapped device byte wise, bytes are stored on every 4th position. */\r
+static __inline void StoreByte(size_t Ptr, int Offset, unsigned __int8 value)\r
+{\r
+       ((volatile unsigned __int8 *)(Ptr))[Offset] = value;\r
+}\r
+\r
+static __inline void StoreDword(size_t Ptr, int Offset, unsigned __int32 value)\r
+{\r
+       ((volatile unsigned __int32 *)(Ptr))[Offset] = value;\r
+}\r
+\r
+\r
+/** write to memory mapped device byte wise through cache. */\r
+static __inline void StoreCachedByte(size_t Ptr, int Offset, unsigned __int8 value, unsigned __int8 *CachedValue)\r
+{\r
+       if (*CachedValue != value)\r
+       {\r
+               *CachedValue = value;\r
+               StoreByte(Ptr,Offset,value);\r
+       }\r
+}\r
+\r
+\r
+/** This inline is used for reading tightly packed OX9162 local configuration registers. */\r
+static __inline unsigned __int8 GetBytePlain(size_t Ptr, int Offset)\r
+{\r
+       return ((volatile unsigned __int8 *)(Ptr))[Offset];\r
+}\r
+\r
+\r
+/****************************************************************\r
+ *                                                              *\r
+ *                 DIGITAL INPUTS & OUTPUTS                     *\r
+ *                                                              *\r
+ ****************************************************************/\r
+\r
+\r
+/** Get data from digital input. */\r
+static int PCT7303DIRead(const DeviceRecord *DevRecord, unsigned channel)\r
+{\r
+       if (channel>=DI_CHANNELS) return HUDAQBADARG;\r
+       return GetBytePlain(DevRecord->DrvRes.Resources.MemResources[0].Base,DINReg);\r
+}\r
+\r
+\r
+/** Write data to digital output. */\r
+static HUDAQSTATUS PCT7303DOWrite(const DeviceRecord *DevRecord, unsigned channel, unsigned value)\r
+{\r
+       if (channel>=DO_CHANNELS) return HUDAQBADARG;\r
+       StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, DOUTReg, value,\r
+                       &((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
+       return HUDAQSUCCESS;\r
+}\r
+\r
+\r
+/** Write one bit to digital output. */\r
+static void PCT7303DOWriteBit(const DeviceRecord *DevRecord, unsigned channel, unsigned bit, int value)\r
+{\r
+       __int8 DoutByte;\r
+\r
+       if (channel>=DO_CHANNELS) return;\r
+       if (bit>=8) return;   //there are only 8 bits available in PCT7303\r
+\r
+       DoutByte = (((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
+       if (value) DoutByte |= (1<<bit);\r
+       else DoutByte &= ~(1<<bit);\r
+\r
+       StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, DOUTReg, DoutByte,\r
+                       & ((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
+}\r
+\r
+\r
+static void PCT7303DOWriteMultipleBits(const DeviceRecord *DevRecord, unsigned channel, unsigned mask, unsigned value)\r
+{\r
+       __int8 DoutByte;\r
+\r
+       if (channel>=DO_CHANNELS) return;\r
+\r
+       DoutByte = (((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
+       DoutByte = (DoutByte & ~mask) | (value & mask);\r
+\r
+       StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, DOUTReg, DoutByte,\r
+                       &((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
+}\r
+\r
+\r
+static double PCT7303DIOGetParameter(unsigned channel, HudaqParameter param)\r
+{\r
+       switch((int)param)\r
+       {\r
+               case HudaqDINUMBITS:\r
+                       return (channel<DI_CHANNELS) ? 8 : WRONG_VALUE;\r
+               case HudaqDONUMBITS:\r
+                       return (channel<DO_CHANNELS) ? 8 : WRONG_VALUE;\r
+               case HudaqDINUMCHANNELS:\r
+                       return DI_CHANNELS;\r
+               case HudaqDONUMCHANNELS:\r
+                       return DO_CHANNELS;\r
+       }\r
+\r
+       return WRONG_VALUE;\r
+}\r
+\r
+\r
+static HUDAQSTATUS PCT7303DIOSetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param, int value)\r
+{\r
+\r
+       switch((int)param)\r
+       {\r
+               case HudaqDINUMBITS:\r
+                       if(channel>=DI_CHANNELS) return WRONG_VALUE;\r
+                       return (value==8) ? 0 : WRONG_VALUE;\r
+               case HudaqDONUMBITS:\r
+                       if(channel>=DI_CHANNELS) return WRONG_VALUE;\r
+                       return (value==8) ? 0 : WRONG_VALUE;\r
+               case HudaqDINUMCHANNELS:\r
+                       return DI_CHANNELS;\r
+               case HudaqDONUMCHANNELS:\r
+                       return DO_CHANNELS;\r
+               case HudaqDOMODE:\r
+                       if(channel>=DO_CHANNELS) return WRONG_VALUE;\r
+                       return HUDAQSUCCESS;\r
+       }\r
+\r
+       return WRONG_VALUE;\r
+}\r
+\r
+\r
+/****************************************************************\r
+ *                                                              *\r
+ *                          ENCODERS                            *\r
+ *                                                              *\r
+ ****************************************************************/\r
+\r
+static double PCT7303BEncGetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param)\r
+{\r
+       //size_t Ptr1;\r
+       PCT_7303B_Private *Cache;\r
+\r
+       Cache = (PCT_7303B_Private *)DevRecord->DrvRes.DriverData;\r
+       if (channel>=ENC_CHANNELS) return WRONG_VALUE;\r
+\r
+       switch(param)\r
+       {\r
+               case HudaqEncRESETONREAD:\r
+                       return(Cache->EncOptions[channel] & IrcResetCounter);\r
+\r
+                       /*\r
+                          case HudaqEncMODE:\r
+                          pCTRi = (IRC_Control *)&(((char *)&(Cache->EncCache))[channel]);\r
+                          return(pCTRi->IRC_MODE);\r
+                          case HudaqEncCOUNTCONTROL:\r
+                          pCTRi = (IRC_Control *)&(((char *)&(Cache->EncCache))[channel]);\r
+                          return(pCTRi->BLOCK_MODE);\r
+                          case HudaqEncRESETMODE:\r
+                          pCTRi = (IRC_Control *)&(((char *)&(Cache->EncCache))[channel]);\r
+                          return(pCTRi->RESET_MODE);\r
+                          case HudaqEncI:\r
+                        *(__int32 *)IrcValue = GetDword(DevRecord->DrvRes.Resources.MemResources[0].Base, IRCSTATUS);\r
+                        return(IrcValue[channel]);\r
+                        */\r
+               case HudaqEncNUMCHANNELS:\r
+                       return ENC_CHANNELS;\r
+       }\r
+\r
+       return WRONG_VALUE;\r
+}\r
+\r
+\r
+static HUDAQSTATUS PCT7303BEncSetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param, double value)\r
+{\r
+       size_t Ptr1;\r
+       PCT_7303B_Private *Cache;\r
+\r
+       Cache = (PCT_7303B_Private *)DevRecord->DrvRes.DriverData;\r
+       if (channel>=ENC_CHANNELS) return HUDAQBADARG;\r
+       Ptr1 = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
+\r
+       switch(param)\r
+       {\r
+               case HudaqEncRESETONREAD:\r
+                       if(value!=0)\r
+                               Cache->EncOptions[channel] |= IrcResetCounter;\r
+                       else\r
+                               Cache->EncOptions[channel] &= ~IrcResetCounter;\r
+                       return HUDAQSUCCESS;\r
+\r
+                       /*\r
+                          case HudaqEncMODE:\r
+                          if (value<0 || value>=4) return HUDAQBADARG;\r
+                        *(unsigned __int32 *)&IrcValue = Cache->EncCache;\r
+                        pCTRi = (IRC_Control *)&IrcValue[channel];\r
+\r
+                        pCTRi->IRC_MODE = (int)value;\r
+                        StoreCachedDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue, &Cache->EncCache);\r
+                        return HUDAQSUCCESS;\r
+\r
+                        case HudaqEncRESETMODE:\r
+                        if (value<0 || value>=7) return HUDAQBADARG;\r
+                        *(unsigned __int32 *)&IrcValue = Cache->EncCache;\r
+                        pCTRi = (IRC_Control *)&IrcValue[channel];\r
+\r
+                        pCTRi->RESET_MODE = (int)value;\r
+                        StoreCachedDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue, &Cache->EncCache);\r
+                        return HUDAQSUCCESS;\r
+\r
+                        case HudaqEncCOUNTCONTROL:\r
+                        if (value<0 || value>=4) return HUDAQBADARG;\r
+                        *(unsigned __int32 *)&IrcValue = Cache->EncCache;\r
+                        pCTRi = (IRC_Control *)&IrcValue[channel];\r
+\r
+                        pCTRi->BLOCK_MODE = (int)value;\r
+                        StoreCachedDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue, &Cache->EncCache);\r
+                        return HUDAQSUCCESS;\r
+                        */\r
+       }\r
+\r
+       return HUDAQNOTSUPPORTED;\r
+}\r
+\r
+\r
+/* static HUDAQSTATUS PCT7303BEncReset(const DeviceRecord *DevRecord, unsigned channel)\r
+   {\r
+   size_t Ptr2;\r
+   MF624_Private *Cache;\r
+   __int8 IrcValue[ENC_CHANNELS];\r
+   IRC_Control *pCTRi;\r
+   char OldResetMode;\r
+\r
+   Cache = (MF624_Private *)DevRecord->DrvRes.DriverData;\r
+   if (channel>=ENC_CHANNELS) return HUDAQBADARG;\r
+   Ptr2 = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
+\r
+ *(unsigned __int32*)&IrcValue = Cache->EncCache;\r
+ pCTRi = (IRC_Control *)&IrcValue[channel];\r
+\r
+ OldResetMode = pCTRi->RESET_MODE; //store original reset mode\r
+ pCTRi->RESET_MODE = 1;                               //reset encoder\r
+ StoreDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue);\r
+ pCTRi->RESET_MODE = OldResetMode;                    //enable counting\r
+ StoreDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue);\r
+ return HUDAQSUCCESS;\r
+ } */\r
+\r
+\r
+static int PCT7303BEncRead(const DeviceRecord *DevRecord, unsigned channel)\r
+{\r
+       size_t Ptr1;\r
+       __int32 RetVal;\r
+       PCT_7303B_Private *Cache;\r
+\r
+       if (channel>=ENC_CHANNELS) return 0;\r
+       Cache = (PCT_7303B_Private *)DevRecord->DrvRes.DriverData;\r
+       Ptr1 = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
+\r
+       // read a value from encoder\r
+       StoreByte(Ptr1, CNTCtrReg, 1<<channel); \r
+       RetVal = GetBytePlain(Ptr1,CNT0SetReg) + \r
+               0x100 * GetBytePlain(Ptr1,CNT1SetReg) +\r
+               0x10000 * GetBytePlain(Ptr1,CNT2SetReg);\r
+\r
+       if(Cache->EncOptions[channel] & IrcResetCounter) //RESET counter on every read\r
+       {\r
+               StoreByte(Ptr1, CNT0SetReg, 0);\r
+               StoreByte(Ptr1, CNT1SetReg, 0);\r
+               StoreByte(Ptr1, CNT2SetReg, 0);\r
+               StoreByte(Ptr1, CNTCtrReg, 0x10<<channel);\r
+       }\r
+\r
+       return RetVal;\r
+}\r
+\r
+\r
+/****************************************************************\r
+ *                                                              *\r
+ *                COUNTERS PWM + Count + Step                   *\r
+ *                                                              *\r
+ ****************************************************************/\r
+\r
+static HUDAQSTATUS PCT7303BPWMWrite(const DeviceRecord *DevRecord, unsigned channel, double frequency, double dutycycle)\r
+{\r
+       double T;\r
+\r
+       if (channel>=CTR_CHANNELS) return HUDAQBADARG;\r
+\r
+       if (frequency<=0) return HUDAQBADARG; //Allow duty cycle 0 and 1 for f=0.\r
+\r
+       T = MASTERFREQUENCY/frequency;\r
+       if(T<1) \r
+       {\r
+               StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg, 1,\r
+                               & ((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->TimerReg);\r
+               return HUDAQPARTIAL;\r
+       }\r
+       if(T>255)\r
+       {\r
+               StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg, 255,\r
+                               & ((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->TimerReg);\r
+               return HUDAQPARTIAL;\r
+       }\r
+\r
+       StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg, \r
+                       (unsigned __int8)T,\r
+                       &((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->TimerReg);\r
+\r
+       return HUDAQSUCCESS;\r
+}\r
+\r
+\r
+static HUDAQSTATUS PCT7303BCtrReset(const DeviceRecord *DevRecord, unsigned channel)\r
+{\r
+       StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg,\r
+                       0, &((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->TimerReg);\r
+       return HUDAQSUCCESS;\r
+}\r
+\r
+\r
+static int PCT7303BCtrRead(const DeviceRecord *DevRecord, unsigned channel)\r
+{\r
+       if (channel>=CTR_CHANNELS) return 0;\r
+       return GetBytePlain(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg);\r
+       return 0;\r
+}\r
+\r
+\r
+/********************************************************************/\r
+\r
+/* Initialization procedure for PCT-7303B card. */\r
+static int InitPCT7303(DeviceRecord *DevRecord, int IniOptions)\r
+{\r
+       PCT_7303B_Private *Cache;\r
+       size_t Base;\r
+\r
+       if (DevRecord==NULL) return -1;\r
+\r
+       if (DevRecord->DrvRes.Resources.NumMemResources<2) return -2;  //insufficient amount of resources\r
+       Cache = DevRecord->DrvRes.DriverData;\r
+       if (Cache==NULL) return -3;\r
+       if (DevRecord->DrvRes.DriverDataSize<sizeof(PCT_7303B_Private)) return -4;\r
+\r
+       DevRecord->pCT = &CTPCT7303;\r
+\r
+       if ((IniOptions & HudaqOpenNOINIT)==0)\r
+       {                           //initialize hardware only if no other application is running\r
+               Base = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
+\r
+               /* Disable interrupts */\r
+               Cache->IRQCfgReg = 0;\r
+               StoreByte(Base, IRQCfgReg, 0);\r
+               Cache->INTEnReg = 0;            /* Clear interrupt logic. */\r
+               StoreByte(Base, INTEnReg, 0);\r
+\r
+               /* Initialization of DI and DO. */\r
+               Cache->DOReg = 0;\r
+               StoreByte(Base, DOUTReg, 0);\r
+\r
+               /* Initialization of internal timer/counter. */\r
+               Cache->TimerReg = 0;\r
+               StoreByte(Base, TimerReg, 0);   /* Stop timer. */\r
+\r
+               /* Initialization of encoders. */\r
+               Cache->CNTEnReg = 0;\r
+               StoreByte(Base, CNTEnReg, 0);   /* Stop encoders. */\r
+       }\r
+\r
+       return 1; //success\r
+}\r
+\r
+\r
+/** Internal cleanup procedure for PCT7303B */\r
+static void DonePCT7303(DeviceRecord *DevRecord)\r
+{\r
+       if (DevRecord==NULL) return;\r
+\r
+       DevRecord->pCT = &CtDummy;\r
+}\r
+\r
+\r
+\r
+/****************************************************************\r
+ *                                                              *\r
+ *                    GET/SET PARAMETERS                        *\r
+ *                                                              *\r
+ ****************************************************************/\r
+\r
+\r
+static HUDAQSTATUS PCT7303IRQSetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param, int value)\r
+{\r
+       size_t Base;\r
+\r
+       Base = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
+\r
+       /*\r
+          switch((int)param)\r
+          {\r
+          case HudaqIRQ+0:\r
+          {\r
+          if(value)\r
+          {\r
+          StoreCachedByte(Base, IRQCfgReg, 1, &((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->IRQCfgReg);\r
+          StoreByte(Base, IRQClrReg, 0xFF);\r
+          StoreCachedByte(Base, INTEnReg, 0x80, &((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->INTEnReg);\r
+          }\r
+          else\r
+          { \r
+          StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, INTEnReg, 0,\r
+          &((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->INTEnReg);\r
+          StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, IRQCfgReg, 0,\r
+          &((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->IRQCfgReg);\r
+          }\r
+          return HUDAQSUCCESS;\r
+          }\r
+          case HudaqIRQ+1:\r
+          return HUDAQSUCCESS;\r
+          }\r
+        */\r
+\r
+       return WRONG_VALUE;\r
+}\r
+\r
+\r
+static double PCT7303IRQGetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param)\r
+{\r
+       switch((int)param)\r
+       {\r
+               case HudaqIRQ+0: \r
+                       return ((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->Hdr.IRQcounter;\r
+       }\r
+       return WRONG_VALUE;\r
+}\r
+\r
+\r
+static HUDAQSTATUS PCT7303SetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param, double value)\r
+{\r
+       switch(param & HudaqSubsystemMASK)\r
+       {\r
+               case HudaqDI:\r
+               case HudaqDO:  return PCT7303DIOSetParameter(DevRecord,channel,param,(int)value);\r
+                              //  case HudaqAI:  \r
+                              //  case HudaqAO:  \r
+               case HudaqEnc: return PCT7303BEncSetParameter(DevRecord,channel,param,(int)value);\r
+                              //  case HudaqPWM:\r
+                              //  case HudaqCtr: \r
+                              //  case HudaqStep:\r
+               case HudaqIRQ: return PCT7303IRQSetParameter(DevRecord,channel,param,(int)value);\r
+       }\r
+       return HUDAQNOTSUPPORTED;\r
+}\r
+\r
+static double PCT7303GetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param)\r
+{\r
+       switch(param & HudaqSubsystemMASK)\r
+       {\r
+               case HudaqDI:\r
+               case HudaqDO:  return PCT7303DIOGetParameter(channel,param);\r
+                              //case HudaqAI:  \r
+                              //case HudaqAO:  \r
+               case HudaqEnc: return PCT7303BEncGetParameter(DevRecord,channel,param);\r
+                              //case HudaqPWM:\r
+                              //case HudaqCtr:\r
+                              //case HudaqStep:\r
+               case HudaqIRQ: return PCT7303IRQGetParameter(DevRecord,channel,param);\r
+       }\r
+       return WRONG_VALUE;\r
+}\r
+\r
+\r
+const CallTable CTPCT7303 =\r
+{\r
+       "PCT7303B", 0x1760, 0x0201,\r
+       InitPCT7303,\r
+       DonePCT7303,\r
+\r
+       PCT7303SetParameter,\r
+       PCT7303GetParameter,\r
+       NULL,\r
+\r
+       // INITIALIZE DI callers\r
+       PCT7303DIRead,\r
+       GenericDIReadBit,           //Generic implementation\r
+       GenericOneDIReadMultiple,\r
+       // INITIALIZE DO callers\r
+       PCT7303DOWrite,\r
+       PCT7303DOWriteBit,\r
+       PCT7303DOWriteMultipleBits,\r
+       GenericDOWriteMultiple,\r
+       // INITIALIZE AI callers\r
+       NULL,\r
+       NULL,\r
+       // INITIALIZE AO callers\r
+       NULL,                                  // Not available\r
+       NULL,\r
+       // INITIALIZE Enc callers\r
+       PCT7303BEncRead,\r
+       NULL,\r
+       // INITIALIZE Ctr callers\r
+       PCT7303BCtrRead,\r
+       PCT7303BCtrReset,\r
+       // INITIALIZE PWM callers\r
+       PCT7303BPWMWrite,            \r
+       NULL,                   // Not available\r
+       NULL,\r
+       // INITIALIZE Step callers\r
+       NULL,                       // Not available\r
+};\r
+\r