]> rtime.felk.cvut.cz Git - mf6xx.git/blob - src/hudaqlib/PCT7303B.c
QEMU mf624.c formatted to make QEMU checkpatch.pl mostly happy.
[mf6xx.git] / src / hudaqlib / PCT7303B.c
1 /****************************************************************/\r
2 /**@file PCT7303B.c:\r
3  * Description: API layer for TEDIA PCT-7303B card.             *\r
4  * Dependency: Windows 32, Windows 64 or Linux                  *\r
5  *                Copyright 2010 Jaroslav Fojtik                *\r
6  ****************************************************************/\r
7 \r
8 #if defined(_WIN32) || defined(_WIN64)\r
9 #include <windows.h>\r
10 #else\r
11 #include <sys/io.h>\r
12 #endif\r
13 #include <malloc.h>\r
14 #include <math.h>\r
15 \r
16 #include "hudaqlib.h"\r
17 #include "hudaq_internal.h"\r
18 \r
19 \r
20 #define DI_CHANNELS   1         ///< Amount of Digital Outputs\r
21 #define DO_CHANNELS   1         ///< Amount of Digital Inputs\r
22 #define DA_CHANNELS   0         ///< Amount of Analog Outputs\r
23 #define AD_CHANNELS   0         ///< Amount of Analog Inputs\r
24 #define ENC_CHANNELS  3         ///< Amount of Encoders\r
25 #define CTR_CHANNELS  1         ///< Amount of counters\r
26 #define STEP_CHANNELS 0         ///< Amount of steppers\r
27 \r
28 \r
29 #define MASTERFREQUENCY 1000    ///< Internal oscillator frequency is 1kHz\r
30 \r
31 #define IrcResetCounter 2       ///< Binary flag for IrcOptions\r
32 \r
33 \r
34 /** Cache of PCT-7303B state */\r
35 typedef struct\r
36 {\r
37         UserDataHeader Hdr;                   ///< General device setup\r
38 \r
39         int EncOptions[ENC_CHANNELS];           ///< Bit options for encoders\r
40 \r
41         unsigned __int8 DOReg;          ///< Port configuration register\r
42         unsigned __int8 IRQCfgReg;\r
43         unsigned __int8 INTEnReg;\r
44         unsigned __int8 TimerReg;\r
45         unsigned __int8 CNTEnReg;\r
46 } PCT_7303B_Private;\r
47 \r
48 \r
49 /** Symbolic aliases for available registers inside BADR1 read. */\r
50 typedef enum\r
51 {\r
52         DINReg     = 0,         // RD only\r
53         DOUTReg    = 4,         // WR only\r
54 \r
55         IRQCfgReg  = 0x180,             // WR only\r
56         IRQStatusReg = 0x180,           // RD only\r
57         IRQClrReg =  0x184,             // WR only\r
58 \r
59         TimerReg =  0x3F0,              // RW\r
60         INTEnReg =  0x18C,              // WR only\r
61 \r
62         CNT0SetReg = 0x200,             // RW\r
63         CNT1SetReg = 0x204,             // RW\r
64         CNT2SetReg = 0x208,             // RW\r
65 \r
66         CNTEnReg = 0x380,               // WR only\r
67         CNTCtrReg= 0x384,               // WR only\r
68 \r
69 } MEM_BAR1;     // Memory space #0 on F1\r
70 \r
71 \r
72 /** write to memory mapped device byte wise, bytes are stored on every 4th position. */\r
73 static __inline void StoreByte(size_t Ptr, int Offset, unsigned __int8 value)\r
74 {\r
75         ((volatile unsigned __int8 *)(Ptr))[Offset] = value;\r
76 }\r
77 \r
78 static __inline void StoreDword(size_t Ptr, int Offset, unsigned __int32 value)\r
79 {\r
80         ((volatile unsigned __int32 *)(Ptr))[Offset] = value;\r
81 }\r
82 \r
83 \r
84 /** write to memory mapped device byte wise through cache. */\r
85 static __inline void StoreCachedByte(size_t Ptr, int Offset, unsigned __int8 value, unsigned __int8 *CachedValue)\r
86 {\r
87         if (*CachedValue != value)\r
88         {\r
89                 *CachedValue = value;\r
90                 StoreByte(Ptr,Offset,value);\r
91         }\r
92 }\r
93 \r
94 \r
95 /** This inline is used for reading tightly packed OX9162 local configuration registers. */\r
96 static __inline unsigned __int8 GetBytePlain(size_t Ptr, int Offset)\r
97 {\r
98         return ((volatile unsigned __int8 *)(Ptr))[Offset];\r
99 }\r
100 \r
101 \r
102 /****************************************************************\r
103  *                                                              *\r
104  *                 DIGITAL INPUTS & OUTPUTS                     *\r
105  *                                                              *\r
106  ****************************************************************/\r
107 \r
108 \r
109 /** Get data from digital input. */\r
110 static int PCT7303DIRead(const DeviceRecord *DevRecord, unsigned channel)\r
111 {\r
112         if (channel>=DI_CHANNELS) return HUDAQBADARG;\r
113         return GetBytePlain(DevRecord->DrvRes.Resources.MemResources[0].Base,DINReg);\r
114 }\r
115 \r
116 \r
117 /** Write data to digital output. */\r
118 static HUDAQSTATUS PCT7303DOWrite(const DeviceRecord *DevRecord, unsigned channel, unsigned value)\r
119 {\r
120         if (channel>=DO_CHANNELS) return HUDAQBADARG;\r
121         StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, DOUTReg, value,\r
122                         &((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
123         return HUDAQSUCCESS;\r
124 }\r
125 \r
126 \r
127 /** Write one bit to digital output. */\r
128 static void PCT7303DOWriteBit(const DeviceRecord *DevRecord, unsigned channel, unsigned bit, int value)\r
129 {\r
130         __int8 DoutByte;\r
131 \r
132         if (channel>=DO_CHANNELS) return;\r
133         if (bit>=8) return;   //there are only 8 bits available in PCT7303\r
134 \r
135         DoutByte = (((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
136         if (value) DoutByte |= (1<<bit);\r
137         else DoutByte &= ~(1<<bit);\r
138 \r
139         StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, DOUTReg, DoutByte,\r
140                         & ((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
141 }\r
142 \r
143 \r
144 static void PCT7303DOWriteMultipleBits(const DeviceRecord *DevRecord, unsigned channel, unsigned mask, unsigned value)\r
145 {\r
146         __int8 DoutByte;\r
147 \r
148         if (channel>=DO_CHANNELS) return;\r
149 \r
150         DoutByte = (((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
151         DoutByte = (DoutByte & ~mask) | (value & mask);\r
152 \r
153         StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, DOUTReg, DoutByte,\r
154                         &((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->DOReg);\r
155 }\r
156 \r
157 \r
158 static double PCT7303DIOGetParameter(unsigned channel, HudaqParameter param)\r
159 {\r
160         switch((int)param)\r
161         {\r
162                 case HudaqDINUMBITS:\r
163                         return (channel<DI_CHANNELS) ? 8 : WRONG_VALUE;\r
164                 case HudaqDONUMBITS:\r
165                         return (channel<DO_CHANNELS) ? 8 : WRONG_VALUE;\r
166                 case HudaqDINUMCHANNELS:\r
167                         return DI_CHANNELS;\r
168                 case HudaqDONUMCHANNELS:\r
169                         return DO_CHANNELS;\r
170         }\r
171 \r
172         return WRONG_VALUE;\r
173 }\r
174 \r
175 \r
176 static HUDAQSTATUS PCT7303DIOSetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param, int value)\r
177 {\r
178 \r
179         switch((int)param)\r
180         {\r
181                 case HudaqDINUMBITS:\r
182                         if(channel>=DI_CHANNELS) return WRONG_VALUE;\r
183                         return (value==8) ? 0 : WRONG_VALUE;\r
184                 case HudaqDONUMBITS:\r
185                         if(channel>=DI_CHANNELS) return WRONG_VALUE;\r
186                         return (value==8) ? 0 : WRONG_VALUE;\r
187                 case HudaqDINUMCHANNELS:\r
188                         return DI_CHANNELS;\r
189                 case HudaqDONUMCHANNELS:\r
190                         return DO_CHANNELS;\r
191                 case HudaqDOMODE:\r
192                         if(channel>=DO_CHANNELS) return WRONG_VALUE;\r
193                         return HUDAQSUCCESS;\r
194         }\r
195 \r
196         return WRONG_VALUE;\r
197 }\r
198 \r
199 \r
200 /****************************************************************\r
201  *                                                              *\r
202  *                          ENCODERS                            *\r
203  *                                                              *\r
204  ****************************************************************/\r
205 \r
206 static double PCT7303BEncGetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param)\r
207 {\r
208         //size_t Ptr1;\r
209         PCT_7303B_Private *Cache;\r
210 \r
211         Cache = (PCT_7303B_Private *)DevRecord->DrvRes.DriverData;\r
212         if (channel>=ENC_CHANNELS) return WRONG_VALUE;\r
213 \r
214         switch(param)\r
215         {\r
216                 case HudaqEncRESETONREAD:\r
217                         return(Cache->EncOptions[channel] & IrcResetCounter);\r
218 \r
219                         /*\r
220                            case HudaqEncMODE:\r
221                            pCTRi = (IRC_Control *)&(((char *)&(Cache->EncCache))[channel]);\r
222                            return(pCTRi->IRC_MODE);\r
223                            case HudaqEncCOUNTCONTROL:\r
224                            pCTRi = (IRC_Control *)&(((char *)&(Cache->EncCache))[channel]);\r
225                            return(pCTRi->BLOCK_MODE);\r
226                            case HudaqEncRESETMODE:\r
227                            pCTRi = (IRC_Control *)&(((char *)&(Cache->EncCache))[channel]);\r
228                            return(pCTRi->RESET_MODE);\r
229                            case HudaqEncI:\r
230                          *(__int32 *)IrcValue = GetDword(DevRecord->DrvRes.Resources.MemResources[0].Base, IRCSTATUS);\r
231                          return(IrcValue[channel]);\r
232                          */\r
233                 case HudaqEncNUMCHANNELS:\r
234                         return ENC_CHANNELS;\r
235         }\r
236 \r
237         return WRONG_VALUE;\r
238 }\r
239 \r
240 \r
241 static HUDAQSTATUS PCT7303BEncSetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param, double value)\r
242 {\r
243         size_t Ptr1;\r
244         PCT_7303B_Private *Cache;\r
245 \r
246         Cache = (PCT_7303B_Private *)DevRecord->DrvRes.DriverData;\r
247         if (channel>=ENC_CHANNELS) return HUDAQBADARG;\r
248         Ptr1 = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
249 \r
250         switch(param)\r
251         {\r
252                 case HudaqEncRESETONREAD:\r
253                         if(value!=0)\r
254                                 Cache->EncOptions[channel] |= IrcResetCounter;\r
255                         else\r
256                                 Cache->EncOptions[channel] &= ~IrcResetCounter;\r
257                         return HUDAQSUCCESS;\r
258 \r
259                         /*\r
260                            case HudaqEncMODE:\r
261                            if (value<0 || value>=4) return HUDAQBADARG;\r
262                          *(unsigned __int32 *)&IrcValue = Cache->EncCache;\r
263                          pCTRi = (IRC_Control *)&IrcValue[channel];\r
264 \r
265                          pCTRi->IRC_MODE = (int)value;\r
266                          StoreCachedDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue, &Cache->EncCache);\r
267                          return HUDAQSUCCESS;\r
268 \r
269                          case HudaqEncRESETMODE:\r
270                          if (value<0 || value>=7) return HUDAQBADARG;\r
271                          *(unsigned __int32 *)&IrcValue = Cache->EncCache;\r
272                          pCTRi = (IRC_Control *)&IrcValue[channel];\r
273 \r
274                          pCTRi->RESET_MODE = (int)value;\r
275                          StoreCachedDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue, &Cache->EncCache);\r
276                          return HUDAQSUCCESS;\r
277 \r
278                          case HudaqEncCOUNTCONTROL:\r
279                          if (value<0 || value>=4) return HUDAQBADARG;\r
280                          *(unsigned __int32 *)&IrcValue = Cache->EncCache;\r
281                          pCTRi = (IRC_Control *)&IrcValue[channel];\r
282 \r
283                          pCTRi->BLOCK_MODE = (int)value;\r
284                          StoreCachedDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue, &Cache->EncCache);\r
285                          return HUDAQSUCCESS;\r
286                          */\r
287         }\r
288 \r
289         return HUDAQNOTSUPPORTED;\r
290 }\r
291 \r
292 \r
293 /* static HUDAQSTATUS PCT7303BEncReset(const DeviceRecord *DevRecord, unsigned channel)\r
294    {\r
295    size_t Ptr2;\r
296    MF624_Private *Cache;\r
297    __int8 IrcValue[ENC_CHANNELS];\r
298    IRC_Control *pCTRi;\r
299    char OldResetMode;\r
300 \r
301    Cache = (MF624_Private *)DevRecord->DrvRes.DriverData;\r
302    if (channel>=ENC_CHANNELS) return HUDAQBADARG;\r
303    Ptr2 = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
304 \r
305  *(unsigned __int32*)&IrcValue = Cache->EncCache;\r
306  pCTRi = (IRC_Control *)&IrcValue[channel];\r
307 \r
308  OldResetMode = pCTRi->RESET_MODE; //store original reset mode\r
309  pCTRi->RESET_MODE = 1;                               //reset encoder\r
310  StoreDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue);\r
311  pCTRi->RESET_MODE = OldResetMode;                    //enable counting\r
312  StoreDword(Ptr2, IRCCTRL, *(unsigned __int32 *)&IrcValue);\r
313  return HUDAQSUCCESS;\r
314  } */\r
315 \r
316 \r
317 static int PCT7303BEncRead(const DeviceRecord *DevRecord, unsigned channel)\r
318 {\r
319         size_t Ptr1;\r
320         __int32 RetVal;\r
321         PCT_7303B_Private *Cache;\r
322 \r
323         if (channel>=ENC_CHANNELS) return 0;\r
324         Cache = (PCT_7303B_Private *)DevRecord->DrvRes.DriverData;\r
325         Ptr1 = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
326 \r
327         // read a value from encoder\r
328         StoreByte(Ptr1, CNTCtrReg, 1<<channel); \r
329         RetVal = GetBytePlain(Ptr1,CNT0SetReg) + \r
330                 0x100 * GetBytePlain(Ptr1,CNT1SetReg) +\r
331                 0x10000 * GetBytePlain(Ptr1,CNT2SetReg);\r
332 \r
333         if(Cache->EncOptions[channel] & IrcResetCounter) //RESET counter on every read\r
334         {\r
335                 StoreByte(Ptr1, CNT0SetReg, 0);\r
336                 StoreByte(Ptr1, CNT1SetReg, 0);\r
337                 StoreByte(Ptr1, CNT2SetReg, 0);\r
338                 StoreByte(Ptr1, CNTCtrReg, 0x10<<channel);\r
339         }\r
340 \r
341         return RetVal;\r
342 }\r
343 \r
344 \r
345 /****************************************************************\r
346  *                                                              *\r
347  *                COUNTERS PWM + Count + Step                   *\r
348  *                                                              *\r
349  ****************************************************************/\r
350 \r
351 static HUDAQSTATUS PCT7303BPWMWrite(const DeviceRecord *DevRecord, unsigned channel, double frequency, double dutycycle)\r
352 {\r
353         double T;\r
354 \r
355         if (channel>=CTR_CHANNELS) return HUDAQBADARG;\r
356 \r
357         if (frequency<=0) return HUDAQBADARG; //Allow duty cycle 0 and 1 for f=0.\r
358 \r
359         T = MASTERFREQUENCY/frequency;\r
360         if(T<1) \r
361         {\r
362                 StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg, 1,\r
363                                 & ((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->TimerReg);\r
364                 return HUDAQPARTIAL;\r
365         }\r
366         if(T>255)\r
367         {\r
368                 StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg, 255,\r
369                                 & ((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->TimerReg);\r
370                 return HUDAQPARTIAL;\r
371         }\r
372 \r
373         StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg, \r
374                         (unsigned __int8)T,\r
375                         &((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->TimerReg);\r
376 \r
377         return HUDAQSUCCESS;\r
378 }\r
379 \r
380 \r
381 static HUDAQSTATUS PCT7303BCtrReset(const DeviceRecord *DevRecord, unsigned channel)\r
382 {\r
383         StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg,\r
384                         0, &((PCT_7303B_Private *)(DevRecord->DrvRes.DriverData))->TimerReg);\r
385         return HUDAQSUCCESS;\r
386 }\r
387 \r
388 \r
389 static int PCT7303BCtrRead(const DeviceRecord *DevRecord, unsigned channel)\r
390 {\r
391         if (channel>=CTR_CHANNELS) return 0;\r
392         return GetBytePlain(DevRecord->DrvRes.Resources.MemResources[0].Base, TimerReg);\r
393         return 0;\r
394 }\r
395 \r
396 \r
397 /********************************************************************/\r
398 \r
399 /* Initialization procedure for PCT-7303B card. */\r
400 static int InitPCT7303(DeviceRecord *DevRecord, int IniOptions)\r
401 {\r
402         PCT_7303B_Private *Cache;\r
403         size_t Base;\r
404 \r
405         if (DevRecord==NULL) return -1;\r
406 \r
407         if (DevRecord->DrvRes.Resources.NumMemResources<2) return -2;  //insufficient amount of resources\r
408         Cache = DevRecord->DrvRes.DriverData;\r
409         if (Cache==NULL) return -3;\r
410         if (DevRecord->DrvRes.DriverDataSize<sizeof(PCT_7303B_Private)) return -4;\r
411 \r
412         DevRecord->pCT = &CTPCT7303;\r
413 \r
414         if ((IniOptions & HudaqOpenNOINIT)==0)\r
415         {                           //initialize hardware only if no other application is running\r
416                 Base = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
417 \r
418                 /* Disable interrupts */\r
419                 Cache->IRQCfgReg = 0;\r
420                 StoreByte(Base, IRQCfgReg, 0);\r
421                 Cache->INTEnReg = 0;            /* Clear interrupt logic. */\r
422                 StoreByte(Base, INTEnReg, 0);\r
423 \r
424                 /* Initialization of DI and DO. */\r
425                 Cache->DOReg = 0;\r
426                 StoreByte(Base, DOUTReg, 0);\r
427 \r
428                 /* Initialization of internal timer/counter. */\r
429                 Cache->TimerReg = 0;\r
430                 StoreByte(Base, TimerReg, 0);   /* Stop timer. */\r
431 \r
432                 /* Initialization of encoders. */\r
433                 Cache->CNTEnReg = 0;\r
434                 StoreByte(Base, CNTEnReg, 0);   /* Stop encoders. */\r
435         }\r
436 \r
437         return 1; //success\r
438 }\r
439 \r
440 \r
441 /** Internal cleanup procedure for PCT7303B */\r
442 static void DonePCT7303(DeviceRecord *DevRecord)\r
443 {\r
444         if (DevRecord==NULL) return;\r
445 \r
446         DevRecord->pCT = &CtDummy;\r
447 }\r
448 \r
449 \r
450 \r
451 /****************************************************************\r
452  *                                                              *\r
453  *                    GET/SET PARAMETERS                        *\r
454  *                                                              *\r
455  ****************************************************************/\r
456 \r
457 \r
458 static HUDAQSTATUS PCT7303IRQSetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param, int value)\r
459 {\r
460         size_t Base;\r
461 \r
462         Base = DevRecord->DrvRes.Resources.MemResources[0].Base;\r
463 \r
464         /*\r
465            switch((int)param)\r
466            {\r
467            case HudaqIRQ+0:\r
468            {\r
469            if(value)\r
470            {\r
471            StoreCachedByte(Base, IRQCfgReg, 1, &((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->IRQCfgReg);\r
472            StoreByte(Base, IRQClrReg, 0xFF);\r
473            StoreCachedByte(Base, INTEnReg, 0x80, &((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->INTEnReg);\r
474            }\r
475            else\r
476            { \r
477            StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, INTEnReg, 0,\r
478            &((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->INTEnReg);\r
479            StoreCachedByte(DevRecord->DrvRes.Resources.MemResources[0].Base, IRQCfgReg, 0,\r
480            &((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->IRQCfgReg);\r
481            }\r
482            return HUDAQSUCCESS;\r
483            }\r
484            case HudaqIRQ+1:\r
485            return HUDAQSUCCESS;\r
486            }\r
487          */\r
488 \r
489         return WRONG_VALUE;\r
490 }\r
491 \r
492 \r
493 static double PCT7303IRQGetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param)\r
494 {\r
495         switch((int)param)\r
496         {\r
497                 case HudaqIRQ+0: \r
498                         return ((PCT_7303B_Private *)DevRecord->DrvRes.DriverData)->Hdr.IRQcounter;\r
499         }\r
500         return WRONG_VALUE;\r
501 }\r
502 \r
503 \r
504 static HUDAQSTATUS PCT7303SetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param, double value)\r
505 {\r
506         switch(param & HudaqSubsystemMASK)\r
507         {\r
508                 case HudaqDI:\r
509                 case HudaqDO:  return PCT7303DIOSetParameter(DevRecord,channel,param,(int)value);\r
510                                //  case HudaqAI:  \r
511                                //  case HudaqAO:  \r
512                 case HudaqEnc: return PCT7303BEncSetParameter(DevRecord,channel,param,(int)value);\r
513                                //  case HudaqPWM:\r
514                                //  case HudaqCtr: \r
515                                //  case HudaqStep:\r
516                 case HudaqIRQ: return PCT7303IRQSetParameter(DevRecord,channel,param,(int)value);\r
517         }\r
518         return HUDAQNOTSUPPORTED;\r
519 }\r
520 \r
521 static double PCT7303GetParameter(const DeviceRecord *DevRecord, unsigned channel, HudaqParameter param)\r
522 {\r
523         switch(param & HudaqSubsystemMASK)\r
524         {\r
525                 case HudaqDI:\r
526                 case HudaqDO:  return PCT7303DIOGetParameter(channel,param);\r
527                                //case HudaqAI:  \r
528                                //case HudaqAO:  \r
529                 case HudaqEnc: return PCT7303BEncGetParameter(DevRecord,channel,param);\r
530                                //case HudaqPWM:\r
531                                //case HudaqCtr:\r
532                                //case HudaqStep:\r
533                 case HudaqIRQ: return PCT7303IRQGetParameter(DevRecord,channel,param);\r
534         }\r
535         return WRONG_VALUE;\r
536 }\r
537 \r
538 \r
539 const CallTable CTPCT7303 =\r
540 {\r
541         "PCT7303B", 0x1760, 0x0201,\r
542         InitPCT7303,\r
543         DonePCT7303,\r
544 \r
545         PCT7303SetParameter,\r
546         PCT7303GetParameter,\r
547         NULL,\r
548 \r
549         // INITIALIZE DI callers\r
550         PCT7303DIRead,\r
551         GenericDIReadBit,           //Generic implementation\r
552         GenericOneDIReadMultiple,\r
553         // INITIALIZE DO callers\r
554         PCT7303DOWrite,\r
555         PCT7303DOWriteBit,\r
556         PCT7303DOWriteMultipleBits,\r
557         GenericDOWriteMultiple,\r
558         // INITIALIZE AI callers\r
559         NULL,\r
560         NULL,\r
561         // INITIALIZE AO callers\r
562         NULL,                                  // Not available\r
563         NULL,\r
564         // INITIALIZE Enc callers\r
565         PCT7303BEncRead,\r
566         NULL,\r
567         // INITIALIZE Ctr callers\r
568         PCT7303BCtrRead,\r
569         PCT7303BCtrReset,\r
570         // INITIALIZE PWM callers\r
571         PCT7303BPWMWrite,            \r
572         NULL,                   // Not available\r
573         NULL,\r
574         // INITIALIZE Step callers\r
575         NULL,                       // Not available\r
576 };\r
577 \r