File: DETECUSE\Detec_hw.cpp

    1 /*
    2 $Header: /vol/baal-vol3/projekt98/quellen/XCTL_32/DETECUSE/Detec_hw.cpp,v 1.17 2004/06/17 19:33:03 reinecke Exp $
    3 
    4 Projekt   : XCTL
    5 Subsystem : Detektoren
    6 Autor     : Jan Picard <picard@informatik.hu-berlin.de> 2001-2002
    7           Institut fuer Informatik,
    8           Humboldt-Universitaet Berlin
    9 Inhalt    : Code fuer die Hardwareklassen, die fuer die Messadapter
   10           die Kommunikation mit der Detektoren-Hardware erledigen
   11 */
   12 #include "internls\evrythng.h"
   13 #include "detecuse\detectorcontroller.h"
   14 
   15 #include "utils\u_utils.h"
   16 #include <fstream.h>
   17 //ap #define STRICT
   18 
   19 
   20 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
   21 
   22 //Verwaltungsstrukturen (Treiber)
   23 extern DeviceList DetectorDrivers;
   24 extern ControllerList DetectorControllers;
   25 
   26 //###########################################################################
   27 // TRadiconController
   28 //###########################################################################
   29 
   30 // storage specifiations
   31 const int LNGMSG= 25;     // length of buffer receive/transmit message
   32 const int LNGPRG= 0x7f0;  // length of buffer program
   33 
   34 // detector internals
   35 // Timeout: Der urspruenglich verwendete Timeout-Wert war 3 'ticks',
   36 // 1 tick= 1/18.2 sec= ca. 55 ms
   37 const int TMOUT= 3*55;
   38 
   39 const long KMGHZ= 500000L;   // frequency base (affects exposure time)
   40 const int NCYCL= 8;         // number of retries for messaging
   41 
   42 //  unknown codes
   43 const unsigned char MONIT= 0x93;      // monitor controller???
   44 const unsigned char PROGR= 0x6c;      // program ready???
   45 
   46 enum responseCode
   47 {
   48         ACK= 0x06,     // acknowledged
   49         NAK= 0x15,       // not acknowledged
   50         CAN= 0x18,       // canceled (not acknowledged)
   51         DLE= 0x10,       // data link escape
   52         EOT= 0x04,       // end of transmission
   53 };
   54 
   55 //! controller function codes
   56 enum EFunctionCode {
   57         CF0= 0x00,     // set parameters
   58         CF1= 0x01,       // count pulses during exposure time
   59         CF2= 0x02,       // count time when number of pulses is set
   60         CF3= 0x03,       // intensimeter
   61         CF5= 0x05,       // stop controller
   62         CF9= 0x09,       // receive result time and pulses
   63         CFB= 0x0b,       // receive current time and pulses
   64         CFF= 0x0f     // load program to card ???
   65 };
   66 
   67 /////////////////////////////////////////////////////////////////
   68 TRadiconController::TRadiconController(EDeviceType _DeviceID, LPTSTR _HardwareID, DeviceList* Devices) 
   69                                                 : Controller(_DeviceID,_HardwareID,1), dataPort(0), controlPort(1)
   70 {
   71         char* szDeviceName= Devices->GetFileName(DeviceID, HardwareID);
   72         if(!szDeviceName)
   73         {
   74                 Hardware= new DummyIo(DeviceID,HardwareID);
   75         }
   76         else
   77         {
   78                 Hardware= new HardwareIo(szDeviceName);
   79         }
   80 }
   81 
   82 TRadiconController::~TRadiconController()
   83 {
   84         _FREEOBJ(Hardware);
   85 }
   86 
   87 BOOL TRadiconController::Check()
   88 {
   89         //ap - noch zu implementieren!!!
   90         return(TRUE);
   91 }
   92 
   93 /*******************************************************************************
   94   procedure: SetParameters
   95   purpose:   upload parameters to controller
   96   result:    0= operation successful
   97              -1= communication error
   98              -2= controller can't make this function to present time or error
   99                   code function
  100              -3= parameter error
  101 ******************************************************************************/
  102 int TRadiconController::SetParameters( unsigned short upperThreshold,
  103                                        unsigned short lowerThreshold,
  104                                        int highvoltage, double exposureTime,
  105                                        unsigned long impulseCount, BOOL bSound )
  106 {
  107         unsigned char bufmsg[LNGMSG];   // buffer receive/transmit message
  108         memset(bufmsg, 0x0, LNGMSG);
  109 
  110         // format energy integral
  111         bufmsg[0]= 0x1;
  112 
  113         // format sound
  114         bufmsg[1]= (unsigned char) (bSound ? 7 : 8);
  115 
  116         // format high voltage do bitshift to get next Byte
  117         bufmsg[7]= (unsigned char) highvoltage;
  118         highvoltage= (highvoltage >> 8) & 0xff;
  119         bufmsg[8]= (unsigned char) highvoltage;
  120 
  121         // format lower threshold do bitshift to get next Byte
  122         bufmsg[9]= (unsigned char) lowerThreshold;
  123         lowerThreshold= (lowerThreshold >> 8) & 0xff;
  124         bufmsg[10]= (unsigned char) lowerThreshold;
  125 
  126         // format upper threshold do bitshift to get next Byte
  127         bufmsg[11]= (unsigned char) upperThreshold;
  128         upperThreshold= (upperThreshold >> 8) & 0xff;
  129         bufmsg[12]= (unsigned char) upperThreshold;
  130 
  131         // determine and format total counts
  132         // do bitshifts to get next bytes
  133         unsigned long wtmr= (unsigned long)(exposureTime * KMGHZ);      // !! Typkonvertierung !!
  134         bufmsg[13]= (unsigned char)(wtmr & 0xff);
  135         bufmsg[14]= (unsigned char)((wtmr >> 8) & 0xff);
  136         bufmsg[15]= (unsigned char)(wtmr >> 16) & 0xff;
  137         bufmsg[16]= (unsigned char)(wtmr >> 24) & 0xff;
  138 
  139         // format impulse count
  140         // do bitshifts to get next bytes
  141         bufmsg[17]= (unsigned char)(impulseCount & 0xff);
  142         bufmsg[18]= (unsigned char)((impulseCount >> 8) & 0xff);
  143         bufmsg[19]= (unsigned char)(impulseCount >> 16) & 0xff;
  144         bufmsg[20]= (unsigned char)(impulseCount >> 24) & 0xff;
  145 
  146         // format interrupt
  147         bufmsg[21]= 0;
  148 
  149         // transmit message for NCYCL cycles or until return value is 0
  150         int j;
  151 
  152         for (int i= 0; i < NCYCL; i++ )
  153         {
  154                 j= TransmitMessage( CF0, bufmsg, LNGMSG );
  155 
  156                 if (j == 0)
  157                         break;
  158 
  159                 if (j == -2)
  160                         return -2;
  161         }
  162 
  163         // if max number of cycles reached and return value is not 0
  164         if (j != 0)
  165                 return -1;
  166 
  167         return 0;
  168 }
  169 
  170 /*******************************************************************************
  171   procedure: Execute
  172   purpose:   issue command to controller
  173   result:     0= operation successful
  174              -1= communication error
  175              -2= controller can't make this function to present time or error
  176                   code function
  177              -3= parameter error (unknown command)
  178 *******************************************************************************/
  179 int TRadiconController::Execute( EOperationMode fun )
  180 {
  181         register int i, j;
  182         EFunctionCode eFunctionCode;
  183         
  184         switch (fun) 
  185         { // depending on the command to issue... (function code filter)                
  186                 case fixedExposureCounts: // count impulses during exposure time
  187                         eFunctionCode= CF1; 
  188                         break;
  189 
  190                 case fixedImpulseCounts: // count time when number of impulses is set
  191                         eFunctionCode= CF2; 
  192                         break;
  193 
  194                 case intensimeter: // intensimeter
  195                         eFunctionCode= CF3; 
  196                         break;
  197 
  198                 case stop: // stop controller
  199                         eFunctionCode= CF5; 
  200                         break;
  201 
  202                 default: // unknown command
  203                         return -3;
  204         }
  205 
  206         // transmit message NCYCL cycles or until return value is 0
  207         for ( i= 0; i < NCYCL; i++ )
  208         {
  209                 j= TransmitMessage( eFunctionCode);
  210 
  211                 if (j == 0)
  212                   break;
  213 
  214                 if (j == -2)
  215                   return -2;
  216         }
  217 
  218         if (j != 0)
  219                 return -1;   // unknown return code
  220 
  221         return 0;
  222 }
  223 
  224 /*******************************************************************************
  225   procedure: GetValues
  226   purpose:   get information from controller
  227   result:    0= operation successful
  228              -1= communication error
  229              -2= controller can't make this function to present time or error
  230                   code function
  231              -3= parameter error
  232              -4= data isn't ready
  233 ******************************************************************************/
  234 int TRadiconController::GetValues( EReadoutMode fun, double *ftmr, unsigned long *imp )
  235 {
  236         register int i, j;
  237         double wftmr;
  238         unsigned long wimp, wtmr, ww;
  239         unsigned char * p;
  240         int l;
  241         /* buffer receive message */
  242         unsigned char bufmsg[LNGMSG];
  243 
  244         EFunctionCode eFunctionCode;
  245 
  246         switch (fun)
  247         {
  248                 case final: // receive result time and impulses
  249                         eFunctionCode= CF9; 
  250                         break;
  251 
  252                 case intermediate: // receive current time and impulses
  253                         eFunctionCode= CFB; 
  254                         break;
  255 
  256                 default: // parameter error
  257                         return -3;
  258         }
  259 
  260         for ( i= 0; i < NCYCL; i++ )
  261         {
  262                 j= ReceiveMessage( eFunctionCode, bufmsg, LNGMSG, l );
  263 
  264                 if ( j == 0 )
  265                         break;
  266 
  267                 if ( (j == -2) || (j == -4) )
  268                         return j;
  269         }
  270 
  271         if ( j != 0 )
  272                 return -1;
  273 
  274         // read number of counts do Bitshifts to cycle through
  275         // the four Bytes of the bufmsg that represent the longint
  276         p= bufmsg;
  277 
  278         wtmr= 0;
  279         ww= 0;
  280         ww= *p;
  281         wtmr= wtmr + ww;
  282         p++;
  283 
  284         ww= 0;
  285         ww= *p;
  286         ww= ww << 8;
  287         wtmr= wtmr + ww;
  288         p++;
  289 
  290         ww= 0;
  291         ww= *p;
  292         ww= ww << 16;
  293         wtmr= wtmr + ww;
  294         p++;
  295 
  296         ww= 0;
  297         ww= *p;
  298         ww= ww << 24;
  299         wtmr= wtmr + ww;
  300         p++;
  301 
  302         // turn number of counts into exposure time do Bitshifts to cycle
  303         // through the four Bytes of the bufmsg that represent the longint
  304         wftmr= wtmr;
  305         *ftmr= wftmr / (KMGHZ);
  306 
  307         // read impulse count
  308         wimp= 0;
  309 
  310         ww= 0;
  311         ww= *p;
  312         wimp= wimp + ww;
  313         p++;
  314 
  315         ww= 0;
  316         ww= *p;
  317         ww= ww << 8;
  318         wimp= wimp + ww;
  319         p++;
  320 
  321         ww= 0;
  322         ww= *p;
  323         ww= ww << 16;
  324         wimp= wimp + ww;
  325         p++;
  326 
  327         ww= 0;
  328         ww= *p;
  329         ww= ww << 24;
  330         wimp= wimp + ww;
  331         *imp= wimp;
  332 
  333         return 0;
  334 }
  335 
  336 /*******************************************************************************
  337   procedure: reset
  338   purpose:   reset controller
  339   synopsis:  void CALLTYPE reset( )
  340   result:    nothing
  341 *******************************************************************************/
  342 void TRadiconController::reset()
  343 {
  344         /* first write state register (port address, that identifies controller) into
  345          data register. then write lower byte of accumulator register to the data
  346          register
  347         _asm {
  348                 mov dx, rs;
  349                 out dx, al;
  350         }
  351         */
  352 
  353         // JP!! Achtung, es ist voellig unklar, welcher Wert geschrieben werden soll,
  354         // da AL nicht initialisiert wurde, schreibe ich hier (willkuerlich) eine 0
  355         Write(controlPort,BYTE(0));
  356 }
  357 
  358 /******************************************************************************
  359  *  Funktionscode zum Controller uebertragen                                  *
  360  *                                                                            *
  361  *  Rueckgabewert:  0   - OK                                                  *
  362  *                 -1   - FEHLER                                              *
  363  *                 -2   - Controller kann die angeforderte Funktion zu diesem *
  364  *                        Zeitpunkt nicht ausfuehren                          *
  365  *                        oder unbekannter Funktionscode                      *
  366  *                 -3   - Controller zum FirmwareUpload bereit                *
  367  *                 -4   - Controller hat Kommunikation abgebrochen            *
  368  ******************************************************************************/
  369 int TRadiconController::TransmitFunctionCode(int nFunctionCode)
  370 {
  371         //Datenregister einlesen...zu welchem Zweck ???
  372         //eingelesener Wert wird nicht weiter verwendet...
  373         //dataPort.In8Bit();    ap
  374         BYTE data;
  375         Read(dataPort,&data);
  376 
  377         //Funktionscode zum Controller uebertragen
  378 
  379         if (out_byte(nFunctionCode) != TRUE)
  380                 return -1;
  381 
  382         //Antwort des Controllers empfangen
  383         unsigned char chControllerAnswer;
  384 
  385         if (in_byte(chControllerAnswer) != TRUE)
  386                 return -1;
  387 
  388         //Controllerantwort != ACK => Fehler spezifizieren...
  389         if (chControllerAnswer != ACK)
  390         {
  391                 //???
  392                 if (nFunctionCode == CFF && chControllerAnswer == PROGR)
  393                         return -3;
  394 
  395                 //Controllerantwort= CAN (Kommunikation abbrechen)
  396                 if (chControllerAnswer == CAN)
  397                         return -4;
  398 
  399                 //Controllerantwort= NAK (unbekannter Funktionscode)
  400                 if (chControllerAnswer == NAK)
  401                         return -2;
  402 
  403                 //unspezifische Controllerantwort
  404                 return -1;
  405         }
  406 
  407         return 0;
  408 }
  409 
  410 /******************************************************************************
  411  *  Nachricht (Funktionscode und Daten) zum Controller uebertragen            *
  412  *                                                                            *
  413  *  Parameter:                                                                *
  414  *    int nFunctionCode           - Funktionscode (Nachricht)                 *
  415  *    unsigned char* lpszMessage  - Zeiger auf Datenpuffer                    *
  416  *    int nMessageLength          - Anzahl der zu uebertragenden Bytes        *
  417  *                                                                            *
  418  *  Rueckgabewert:  0   - OK                                                  *
  419  *                 -1   - FEHLER                                              *
  420  *                 -2   - Controller kann die angeforderte Funktion zu diesem *
  421  *                        Zeitpunkt nicht ausfuehren                          *
  422  *                        oder unbekannter Funktionscode                      *
  423  *                 -3   - Checksummenfehler                                   *
  424  ******************************************************************************/
  425 int TRadiconController::TransmitMessage(int nFunctionCode, unsigned char* lpszMessage,
  426                                 int nMessageLength)
  427 {
  428   int nRetCode= TransmitFunctionCode(nFunctionCode);
  429 
  430   if ( nRetCode != 0)
  431   {
  432     if ( nRetCode == -3)
  433       return 0;
  434 
  435     return nRetCode;
  436   }
  437 
  438   int nChecksum= 0;  //JP!! Test: Checksumme als UCHAR
  439 
  440   //Datenpuffer byteweise zum Controller uebertragen...
  441 
  442   for (int i= 0; i < nMessageLength; i++)
  443   { //Byte aus dem Datenpuffer zum Controller uebertragen
  444 
  445     if (out_byte(*lpszMessage) != TRUE)
  446       return -1;
  447 
  448     //gesendete Bytes aufsummieren (fuer Checksumme)
  449     nChecksum += *lpszMessage;
  450 
  451     //Wenn ein zu uebertragendes Byte den gleichen Wert wie der Steuercode DLE
  452     //besitzt, so muß dieses Byte zweimal hintereinander uebertragen werden,
  453     //um die Steuercodebedeutung aufzuheben
  454     if (*lpszMessage == 0x10) //*p == DLE
  455     { //zweites senden des Bytes
  456 
  457       if (out_byte(*lpszMessage) != TRUE)
  458         return -1;
  459 
  460       //gesendete Bytes aufsummieren (fuer Checksumme)
  461       nChecksum += *lpszMessage;
  462     }
  463 
  464     //Pufferzeiger inkrementieren
  465     lpszMessage++;
  466   }
  467 
  468   //Nachricht DLE zum Controller uebertragen => Daten vollstaendig uebertragen
  469   if (out_byte(DLE) != TRUE)
  470     return -1;
  471 
  472   //gesendet Bytes aufsummieren (fuer Checksumme)
  473   nChecksum += DLE;
  474 
  475   //Nachricht EOT zum Controller uebertragen
  476   //=> Nachrichtenuebertragung abschliessen
  477   if (out_byte(EOT) != TRUE)
  478     return -1;
  479 
  480   nChecksum += EOT; //gesendete Bytes aufsummieren (fuer Checksumme)
  481   nChecksum= ~nChecksum;   //bitweise Negation (1er-Komplement)
  482   nChecksum++;      //=> 2er-Komplement
  483 
  484   //ermittelte Checksumme zum Controller uebertragen
  485   if (out_byte(nChecksum) != TRUE)
  486     return -1;
  487 
  488   unsigned char chControllerAnswer;
  489 
  490   if (in_byte(chControllerAnswer) != TRUE)
  491     return -1;
  492 
  493   if (chControllerAnswer == NAK)
  494     return -3;      // NAK= Checksummenfehler
  495 
  496   return 0; //Funktion mit OK beenden
  497 }
  498 
  499 /******************************************************************************
  500  *  Nachricht vom Controller empfangen                                        *
  501  *  (Funktionscode dem Controller uebermitteln und Ergebnisdaten empfangen)   *
  502  *                                                                            *
  503  *  Parameter:                                                                *
  504  *    int nFunctionCode           - Funktionscode (Nachricht)                 *
  505  *    unsigned char* lpszMessage  - Zeiger auf Datenpuffer                    *
  506  *    int nMaxMessageLength       - max. Laenge der zu empfangenden Daten     *
  507  *    int& nRealMessageLength     - Zeiger auf Anzahl der empfangenen Daten   *
  508  *                                                                            *
  509  *  Rueckgabewert:  0   - OK                                                  *
  510  *                 -1   - FEHLER                                              *
  511  *                 -2   - Controller kann die angeforderte Funktion zu diesem *
  512  *                        Zeitpunkt nicht ausfuehren                          *
  513  *                        oder unbekannter Funktionscode                      *
  514  *                 -3   - Checksummenfehler                                   *
  515  *                 -4   - Daten stehen nicht bereit                           *
  516  ******************************************************************************/
  517 int TRadiconController::ReceiveMessage(int nFunctionCode, unsigned char* lpszMessage,
  518                                int nMaxMessageLength, int& nRealMessageLength)
  519 {
  520   int nRetCode= TransmitFunctionCode(nFunctionCode);
  521 
  522   if ( nRetCode != 0)
  523   {
  524     if ( nRetCode == -3)
  525       return 0;
  526 
  527     return nRetCode;
  528   }
  529 
  530   int nChecksum= 0;
  531   nRealMessageLength= 0; //Anzahl der empfangenen Daten mit 0 initialisieren
  532 
  533   //Daten byteweise vom Controller empfangen bis die max. Anzahl erreicht ist
  534   //oder die Datenuebertragung durch DLE vom Controller beendet wird
  535   unsigned char chControllerAnswer1, chControllerAnswer2;
  536 
  537   while (nRealMessageLength < nMaxMessageLength)
  538   { //Byte vom Controller empfangen
  539 
  540     if (in_byte(chControllerAnswer1) != TRUE)
  541       return -1;
  542 
  543     //empfangene Bytes aufsummieren (fuer Checksumme)
  544     nChecksum += chControllerAnswer1;
  545 
  546     //empfangenes Byte= DLE => testen ob Steuercode(DLE) oder Datenwert(10h)
  547     if (chControllerAnswer1 == DLE)
  548     {  //Folgebyte vom Controller empfangen
  549 
  550       if (in_byte(chControllerAnswer2) != TRUE)
  551         return -1;
  552 
  553       nChecksum += chControllerAnswer2;
  554 
  555       //empfangenes Byte= EOT (Ende der Uebertragung) => vorheriges Byte
  556       //war Steuercode DLE => Datenempfang vorzeitig abbrechen
  557       if (chControllerAnswer2 == EOT)
  558         break;
  559 
  560       //empfangenes Byte != DLE => vorheriges Byte war weder Steuercode(DLE)
  561       //noch Datenwert(10h) => Funktion mit FEHLER beenden
  562       if (chControllerAnswer2 != DLE)
  563         return -1;
  564     }
  565 
  566     //empfangenes Byte in den Datenpuffer uebernehmen
  567     *lpszMessage= chControllerAnswer1;
  568 
  569     //Pufferzeiger inkrementieren
  570     lpszMessage++;
  571 
  572     //Anzahl der empfangenen Daten inkrementieren
  573     nRealMessageLength++;
  574   }
  575 
  576   //letztes Byte vom Controller empfangen (zur Ueberpruefung der Checksumme)
  577   if (in_byte(chControllerAnswer1) != TRUE)
  578     return -1;
  579 
  580   //Checksumme pruefen
  581   nChecksum= (nChecksum + chControllerAnswer1) & 0xff;
  582 
  583   //Checksumme != 0 => NAK (wegen Checksummenfehler) an den Controller senden
  584   if (nChecksum != 0)
  585   { //Nachricht NAK (Checksummenfehler) an den Controller uebermitteln
  586 
  587     if (out_byte(NAK) != TRUE)
  588       return -1;
  589 
  590     //Funktion mit Fehlercode -3 beenden
  591     return -3;
  592   }
  593 
  594   //Nachricht ACK (Checksumme OK) an Controller uebermitteln
  595   if (out_byte(ACK) != TRUE)
  596     return -1;
  597 
  598   return 0;
  599 }
  600 
  601 /******************************************************************************
  602  *  Datenbyte zum Controller uebertragen                                      *
  603  ******************************************************************************/
  604 BOOL TRadiconController::out_byte(unsigned char d)
  605 {
  606   unsigned long dwStart, dwNow;
  607 
  608   //(1) aktuelle Systemzeit ermitteln
  609   dwStart= dwNow= CurrentTime();
  610 
  611   //Warten auf 'Bereit-Zustand' des Controllers innerhalb einer bestimmten Zeit
  612   //(TIMEOUT-Schleife)
  613 
  614   while (( dwNow - dwStart ) < TMOUT)
  615   {
  616     //Controllerstatus ermitteln
  617 
  618     if (IsReadyToWrite() == TRUE)
  619     {
  620       //Byte vom Controller empfangen (Datenregister lesen)
  621       //dataPort.Out8Bit(d);    ap
  622                 Write(dataPort,(BYTE)d);
  623       return TRUE;
  624     }
  625 
  626     //(2) aktuelle Systemzeit ermitteln
  627     dwNow= CurrentTime();
  628 
  629     //Fehler: zuletzt gemessene Systemzeit(2) liegt vor der ersten gemessenen
  630     //Systemzeit(1) => Anpassen der ersten Systemzeit(1)
  631     //=> bisher verstrichene Zeit wird zurueckgesetzt => TIMEOUT beginnt erneut
  632     if (dwNow < dwStart)
  633       dwStart= dwNow;
  634   }
  635 
  636   //Daten stehen nicht bereit
  637   return FALSE;
  638 }
  639 
  640 /******************************************************************************
  641  *  Datenbyte vom Controller empfangen                                        *
  642  ******************************************************************************/
  643 BOOL TRadiconController::in_byte(unsigned char &d)
  644 {
  645   unsigned long dwStart, dwNow;
  646 
  647   //(1) aktuelle Systemzeit ermitteln
  648   dwStart= dwNow= CurrentTime();
  649 
  650   //Warten auf 'Bereit-Zustand' des Controllers innerhalb einer bestimmten Zeit
  651   //(TIMEOUT-Schleife)
  652 
  653   while (( dwNow - dwStart ) < TMOUT)
  654   {
  655     //Controllerstatus ermitteln
  656 
  657     if (IsReadyToRead() == TRUE)
  658     {
  659       //Byte vom Controller empfangen (Datenregister lesen)
  660       //d= dataPort.In8Bit();   ap
  661                 Read(dataPort,&d);
  662       return TRUE;
  663     }
  664 
  665     //(2) aktuelle Systemzeit ermitteln
  666     dwNow= CurrentTime();
  667 
  668     //Fehler: zuletzt gemessene Systemzeit(2) liegt vor der ersten gemessenen
  669     //Systemzeit(1) => Anpassen der ersten Systemzeit(1)
  670     //=> bisher verstrichene Zeit wird zurueckgesetzt => TIMEOUT beginnt erneut
  671     if (dwNow < dwStart)
  672       dwStart= dwNow;
  673   }
  674 
  675   //Daten stehen nicht bereit
  676   return FALSE;
  677 }
  678 
  679 /******************************************************************************
  680  *  Testen ob Controller zur Datenuebergabe (senden) bereit                   *
  681  *                                                                            *
  682  *  Rueckgabewert:  TRUE   - Controller bereit (Datenregister nicht leer)     *
  683  *                  FALSE  - Controller nicht bereit (Datenregister leer)     *
  684  ******************************************************************************/
  685 BOOL TRadiconController::IsReadyToRead()
  686 { 
  687   //Steuerregister lesen und auswerten...
  688   //JP Achtung: Der Controller ist zum Auslesen bereit,
  689   //JP wenn das Ergebnis != 0 ist. Beim Bereitschaftstest zum Senden ist der
  690   //JP Controller bereit, wenn das Ergebnis == 0 ist
  691   //return (( controlPort.In8Bit() & 0x02 ) != 0);      ap
  692         BYTE data;
  693         Read(controlPort,&data);
  694         return(( data & 0x02 ) != 0);
  695 }
  696 
  697 /******************************************************************************
  698  *  Testen ob Controller zur Datenuebernahme (empfangen) bereit               *
  699  *                                                                            *
  700  *  Rueckgabewert:  TRUE   - Controller bereit (Datenregister nicht leer)     *
  701  *                  FALSE  - Controller nicht bereit (Datenregister leer)     *
  702  ******************************************************************************/
  703 BOOL TRadiconController::IsReadyToWrite()
  704 { 
  705   //Steuerregister lesen und Status auswerten...
  706   //return (( controlPort.In8Bit() & 0x01 ) == 0);      ap
  707         BYTE data;
  708         Read(controlPort,&data);
  709         //rh return(( data & 0x01 ) != 0);
  710         return(( data & 0x01 ) == 0);
  711 
  712 }
  713 
  714 /*******************************************************************************
  715 --- UploadFirmware ---
  716 upload controller firmware
  717  
  718 return values:   0= operation successful
  719                 -1= communication error
  720                 -2= controller rejects connect
  721                 -3= error using firmware file
  722                 -4= unspecified error
  723 *******************************************************************************/
  724 int TRadiconController::UploadFirmware(void)
  725 {
  726   // open firmware file
  727   char szFileName[MaxString];
  728   sprintf(szFileName, "%sscs.prg", GetDirectory());
  729   ifstream ifile(szFileName, ios::in | ios::binary);
  730 
  731   if ( ifile.fail() )
  732   {
  733     MessageBox(0, "Kann Radicon-Firmwaredatei scs.prg nicht oeffnen!",
  734                "Error", MBINFO );
  735     return -3;
  736   }
  737 
  738   // check file size
  739   ifile.seekg (0, ios::end);
  740 
  741   int nFileSize= ifile.tellg();
  742 
  743   ifile.seekg (0, ios::beg);
  744 
  745   if ( nFileSize != LNGPRG )
  746   {
  747     MessageBox(0, "Die Radicon-Firmwaredatei scs.prg hat nicht die korrekte Laenge!",
  748                "Error", MBINFO );
  749     return -3;
  750   }
  751 
  752   unsigned char* pBuf= new unsigned char[LNGPRG];
  753 
  754   if ( pBuf == NULL )
  755   {
  756     MessageBox(0, "Nicht genug Speicher!",
  757                "Error", MBINFO );
  758     return -4;
  759   }
  760 
  761   // read content of file into memory
  762   ifile.read(pBuf, LNGPRG);
  763 
  764   ifile.close();
  765 
  766   // This method reads bytes from controller multiple times, but can't
  767   // say why. This behavior is preserved from the old C-sources, because
  768   // I don't know the Radicon communication protocol.
  769 
  770   unsigned char d;
  771 
  772   in_byte(d);    // read a byte from controller - why???
  773 
  774   Execute(stop);
  775 
  776   // send firmware to controller
  777   int nRetCode;
  778 
  779   int i;
  780 
  781   for ( i= 0; i < NCYCL; i++ )
  782   {
  783     nRetCode= TransmitMessage( CFF, pBuf, LNGPRG );
  784 
  785     if (nRetCode == -2)
  786     {
  787       _FREEOBJ(pBuf);
  788       return -2;
  789     }
  790 
  791     if (nRetCode == 0)
  792       break;
  793   }
  794 
  795   _FREEOBJ(pBuf);
  796 
  797   if ( i == NCYCL )
  798     return -1;    // Timeout erreicht
  799 
  800   if ( d == MONIT )
  801     in_byte(d);
  802 
  803   return 0;
  804 }
  805 
  806 /******************************************************************************
  807  *  Zeit seit dem Start des Systems in Millisekunden ermitteln                *
  808  *                                                                            *
  809  *  Rueckgabewert:  dword - Systemzeit in Millisekunden                       *
  810  ******************************************************************************/
  811 DWORD TRadiconController::CurrentTime()
  812 {
  813   return GetTickCount();
  814 }
  815 
  816 
  817 //###########################################################################
  818 // TAm9513
  819 //###########################################################################
  820 
  821 const int IoWaiTAm9513= 43;
  822 // Chip
  823 const BYTE CHIP1= 0x0;
  824 const BYTE CHIP2= 0x1;
  825 const BYTE DIGITAL= 0x2;
  826 
  827 const BYTE BIT= 0x4;
  828 const BYTE CODE= 0x5;
  829 
  830 // IO-Addressen Offset
  831 const int DATA= 0x0;
  832 const int CMD= 0x1;
  833 
  834 // Gruppen
  835 const BYTE CNT1= 0x01;
  836 const BYTE CNT2= 0x02;
  837 const BYTE CNT3= 0x03;
  838 const BYTE CNT4= 0x04;
  839 const BYTE CNT5= 0x05;
  840 const BYTE CTRG= 0x07;
  841 
  842 // Zaehler-Id Bit's
  843 const BYTE CTB1= 0x01;
  844 const BYTE CTB2= 0x02;
  845 const BYTE CTB3= 0x04;
  846 const BYTE CTB4= 0x08;
  847 const BYTE CTB5= 0x10;
  848 
  849 // Register der Gruppen
  850 const BYTE CMR= 0x00; // Mode-Register
  851 const BYTE CLR= 0x08; // Load-Register
  852 const BYTE CHR= 0x10; // Hold-Register
  853 const BYTE CHIR= 0x18; // Hold+Inc-Register
  854 const BYTE ALM1= 0x00; // Alarm-Register 1
  855 const BYTE ALM2= 0x08; // Alarm-Register 2
  856 const BYTE MMR= 0x10; // Master-Mode-Register
  857 const BYTE STS= 0x18; // Status-Register (8 Bit)
  858 // Funktions-Bit fuer CMR
  859 const WORD CB_UP= 3; // aufwaerts zaehlen
  860 const WORD CB_BCD= 4; // BCD zaehlen
  861 const WORD CB_REPEAT= 5; // automatisch neu starten
  862 const WORD CB_RLorH= 6; // laden von L-Reg oder H-Reg
  863 const WORD CB_ENGATE= 7; // special gate
  864 const WORD CB_FALLEG= 12; // mit steigender Flanke zaehlen
  865 // Funktions-Bit fuer MMR
  866 const WORD MB_CMP1E= 2;
  867 const WORD MB_CMP2E= 3;
  868 const WORD MB_NFOUT= 12;
  869 const WORD MB_16BIT= 13;
  870 const WORD MB_DIS_INC= 14;
  871 const WORD MB_BCD_DIV= 15;
  872 // Funktions-Code fuer CMR (nur Setzen mit |)
  873 const WORD CC_CNTM1= 0x0000;
  874 const WORD CC_NOGATE= 0x0000;
  875 const WORD CC_AHTCNM1= 0x2000;
  876 const WORD CC_AHNP1= 0x4000;
  877 const WORD CC_AHNM1= 0x6000;
  878 const WORD CC_AHN= 0x8000;
  879 const WORD CC_ALN= 0xA000;
  880 const WORD CC_AHEGN= 0xC000;
  881 const WORD CC_ALEGN= 0xE000;
  882 // Output-Control
  883 const WORD CC_I_OLow= 0x0000;
  884 const WORD CC_A_HTCP= 0x0001;
  885 const WORD CC_TCTOG= 0x0002;
  886 const WORD CC_I_OTRI= 0x0004;
  887 const WORD CC_A_LTCP= 0x0005;
  888 
  889 // Quellen-Bezeichner fuer CMR und MMR
  890 const WORD C_CNM1= 0x0; // F1 MMR
  891 const WORD C_SRC1= 0x1;
  892 const WORD C_SRC2= 0x2;
  893 const WORD C_SRC3= 0x3;
  894 const WORD C_SRC4= 0x4;
  895 const WORD C_SRC5= 0x5;
  896 const WORD C_GATE1= 0x6;
  897 const WORD C_GATE2= 0x7;
  898 const WORD C_GATE3= 0x8;
  899 const WORD C_GATE4= 0x9;
  900 const WORD C_GATE5= 0xA;
  901 const WORD C_F1= 0xB;
  902 const WORD C_F2= 0xC;
  903 const WORD C_F3= 0xD;
  904 const WORD C_F4= 0xE;
  905 const WORD C_F5= 0xF;
  906 
  907 
  908 //******** Methoden für den Zähler-IC Am9513A **********************************
  909 //Wieviele Detektoren können an diesen Controller angeschlossen werden???
  910 TGenericController::TGenericController(EDeviceType _DeviceID, LPTSTR _HardwareID, DeviceList* Devices) 
  911                                                 : Controller(_DeviceID,_HardwareID,5),bIsStopped(FALSE),bIsLatched(FALSE),
  912                                                   wLowTicks(1000),wHighTicks(100),wLowCounts(1000),wHighCounts(100),
  913                                                   nbChipId(0)
  914 {
  915         char* szDeviceName= Devices->GetFileName(DeviceID, HardwareID);
  916         if(!szDeviceName)
  917         {
  918                 Hardware= new DummyIo(DeviceID,HardwareID);
  919         }
  920         else
  921         {
  922                 Hardware= new HardwareIo(szDeviceName);
  923         }
  924 }
  925 
  926 TGenericController::~TGenericController()
  927 {
  928         _FREEOBJ(Hardware)
  929 }
  930 
  931 BOOL TGenericController::Check()
  932 {
  933         //ap - noch zu implementieren!!!
  934         return(TRUE);
  935 }
  936 
  937 int TGenericController::Init(float _fTimeCorrection)
  938 {
  939         //ap
  940         fTimeCorrection= _fTimeCorrection;
  941 
  942         // Kommunikations-Test
  943         ChooseDataPtr( CNT1, CMR );
  944         WriteData( 0xA121 );
  945         ChooseDataPtr( CNT1, CMR );
  946 
  947         if ( ReadData() != 0xA121 )
  948         return FALSE;
  949 
  950         // Zähler zurücksetzen
  951         Reset();
  952         WriteCmd( 0xF9 );
  953 
  954         // Konfigurieren des Mastermode-Register
  955         ChooseDataPtr( CTRG, MMR );
  956         WriteData( 0xCA00 ); // F1 --> FOUT
  957 
  958         // Konfigurieren des TimeTick-Zähler
  959         ChooseDataPtr( CNT1, CMR );
  960         WriteData( 0xA121 );
  961 
  962         ChooseDataPtr( CNT2, CMR );
  963         WriteData( 0x0202 );
  964 
  965         // Konfigurieren des Impuls-Zähler
  966         ChooseDataPtr( CNT3, CMR );
  967         WriteData( 0xA321 );
  968 
  969         ChooseDataPtr( CNT4, CMR );
  970         WriteData( 0x0402 );
  971 
  972         // Konfigurieren des Akustik-Zähler
  973         ChooseDataPtr( CNT5, CMR );
  974         WriteData( 0x0C21 );
  975 
  976         return TRUE;
  977 }
  978 
  979 int TGenericController::IOCTL( EIOCCmd cmd )
  980 {
  981         DWORD dwData= 0;
  982         return IOCTL( cmd, dwData );
  983 }
  984 
  985 int TGenericController::IOCTL( EIOCCmd cmd, DWORD& param )
  986 {
  987         WORD regH, regL;
  988         WORD wValue;
  989 
  990         switch ( cmd )
  991         {
  992                 case iocSetTimeTicks:
  993                         // Zerlegung in ein Produkt;
  994                         param= ( DWORD ) ( ( double ) param * fTimeCorrection );
  995                         SplitNumber( param, wLowTicks, wHighTicks );
  996                         ChooseDataPtr( CNT1, CLR );
  997                         WriteData( wLowTicks );
  998                         ChooseDataPtr( CNT2, CLR );
  999                         WriteData( wHighTicks ); // TC Toggle
 1000                         param= ( DWORD ) wLowTicks * wHighTicks;
 1001                         param= ( DWORD ) ( ( double ) param / fTimeCorrection );
 1002                         break;
 1003 
 1004                 case iocSetCounts:
 1005                         SplitNumber( param, wLowCounts, wHighCounts );
 1006                         param= ( DWORD ) wLowCounts * wHighCounts;
 1007                         ChooseDataPtr( CNT3, CLR );
 1008                         WriteData( wLowCounts );
 1009                         ChooseDataPtr( CNT4, CLR );
 1010                         WriteData( wHighCounts ); // TC Toggle
 1011                         break;
 1012 
 1013                 case iocStopCCDTiming:
 1014                         DisarmC( CTB1 | CTB2 );
 1015                         SetToggleOut( CNT2 );
 1016                         bIsStopped= TRUE;
 1017                         break;
 1018 
 1019                 case iocStartCCDTiming:
 1020                         if ( !bIsStopped )
 1021                                 DisarmC( CTB1 | CTB2 );
 1022 
 1023                         ChooseDataPtr( CNT1, CMR );
 1024                         // wValue= 0xA121;
 1025                         wValue= 0x0121;
 1026                         WriteData( wValue );
 1027 
 1028                         ChooseDataPtr( CNT2, CMR );
 1029                         // wValue= 0x0202;
 1030                         wValue= 0x0222;
 1031                         WriteData( wValue );
 1032 
 1033                         bIsStopped= FALSE;
 1034                         bIsLatched= FALSE;
 1035 
 1036                         LoadC( CTB1 | CTB2 );
 1037                         LoadC( CTB1 | CTB2 );
 1038 
 1039                         SetToggleOut( CNT2 );
 1040                         SetToggleOut( CNT4 );
 1041 
 1042                         ClearToggleOut( CNT1 );
 1043                         ClearToggleOut( CNT3 );
 1044 
 1045                         ArmC( CTB1 | CTB2 );
 1046                         break;
 1047 
 1048                 case iocStartCCDShot:
 1049                         if ( !bIsStopped )
 1050                                 DisarmC( CTB1 | CTB2 );
 1051 
 1052                         bIsStopped= FALSE;
 1053                         bIsLatched= FALSE;
 1054 
 1055                         LoadC( CTB1 | CTB2 );
 1056                         LoadC( CTB1 | CTB2 );
 1057 
 1058                         SetToggleOut( CNT2 );
 1059                         SetToggleOut( CNT4 );
 1060 
 1061                         ClearToggleOut( CNT1 );
 1062                         ClearToggleOut( CNT3 );
 1063 
 1064                         ArmC( CTB1 | CTB2 );
 1065                         break;
 1066 
 1067                 case iocReadTicks:
 1068                         if ( !bIsLatched )
 1069                         {
 1070                                 DisarmC( CTB1 | CTB2 | CTB3 | CTB4 );
 1071                                 bIsStopped= TRUE;
 1072                                 LatchToHoldC( CTB1 | CTB2 | CTB3 | CTB4 );
 1073                                 bIsLatched= TRUE;
 1074                         }
 1075                         ChooseDataPtr( CNT1, CHR );
 1076                         regL= ReadData( );
 1077                         ChooseDataPtr( CNT2, CHR );
 1078                         regH= ReadData( );
 1079                         param= ( DWORD ) ( wHighTicks - regH ) * ( DWORD ) wLowTicks;
 1080                         param += ( DWORD ) ( wLowTicks - regL );
 1081                         param= ( DWORD ) ( ( double ) param / fTimeCorrection );
 1082                         break;
 1083 
 1084                 case iocReadCounts:
 1085                         if ( !bIsLatched )
 1086                         {
 1087                                 DisarmC( CTB1 | CTB2 | CTB3 | CTB4 );
 1088                                 bIsStopped= TRUE;
 1089                                 LatchToHoldC( CTB1 | CTB2 | CTB3 | CTB4 );
 1090                                 bIsLatched= TRUE;
 1091                         }
 1092 
 1093                         ChooseDataPtr( CNT3, CHR );
 1094                         regL= ReadData( );
 1095                         ChooseDataPtr( CNT4, CHR );
 1096                         regH= ReadData( );
 1097                         param= ( DWORD ) ( wHighCounts - regH ) * ( DWORD ) wLowCounts;
 1098                         param += ( DWORD ) ( wLowCounts - regL );
 1099                         break;
 1100 
 1101                 case iocConfigureAcustic:
 1102                         ChooseDataPtr( CNT5, CLR );
 1103                         WriteData( ( WORD ) param );
 1104                         LoadAndArmC( CTB5 );
 1105                         break;
 1106 
 1107                 case iocStartCounting:
 1108                         DisarmC( CTB1 | CTB2 | CTB3 | CTB4 );
 1109                         bIsStopped= FALSE;
 1110                         bIsLatched= FALSE;
 1111                         LoadC( CTB1 | CTB2 | CTB3 | CTB4 );
 1112                         DelayTime( 1 );
 1113                         LoadC( CTB1 | CTB2 | CTB3 | CTB4 );
 1114                         ClearToggleOut( CNT1 );
 1115                         ClearToggleOut( CNT3 );
 1116                         SetToggleOut( CNT2 );
 1117                         SetToggleOut( CNT4 );
 1118                         DelayTime( 1 );
 1119                         ArmC( CTB1 | CTB2 | CTB3 | CTB4 );
 1120                         break;
 1121 
 1122                 case iocIsCountingReady:
 1123                         switch ( 0x14 & ReadStatus( ) )
 1124                         {
 1125                                 case 0x14: 
 1126                                         param= 0; 
 1127                                         break; // no counter ready
 1128 
 1129                                 case 0x10: 
 1130                                         param= 1; 
 1131                                         break; // time counter ready
 1132 
 1133                                 case 0x04: 
 1134                                         param= 2; 
 1135                                         break; // impulse counter ready
 1136 
 1137                                 default: 
 1138                                         param= 3;
 1139                         }
 1140                         return (int)param;
 1141 
 1142                 case iocStopCounting:
 1143                         DisarmC( CTB1 | CTB2 | CTB3 | CTB4 );
 1144                         bIsStopped= TRUE;
 1145                         break;
 1146         }
 1147 
 1148         return TRUE;
 1149 }
 1150 
 1151 BOOL TGenericController::SplitNumber( DWORD value, WORD& low, WORD& high )
 1152 {
 1153         // in case of any changes notify the function IOCTL()
 1154         if ( value < 0xF000 )
 1155         {
 1156                 high= 1;
 1157                 low= ( WORD ) value;
 1158                 return TRUE;
 1159         }
 1160 
 1161         long f= value;
 1162         long f1= 4;
 1163         long f2= value / f1;
 1164         int cnt= 1000;
 1165         long fail;
 1166 
 1167         while ( cnt-- )
 1168         {
 1169                 fail= f - f1 * f2;
 1170 
 1171                 if ( ( f1 > 0xE000 ) || ( f2 > 0xE000 ) )
 1172                 {
 1173                         if ( f1 < f2 )
 1174                         {
 1175                                 f1 *= 2;
 1176                                 f2 /= 2;
 1177                         }
 1178                         else
 1179                         {
 1180                                 f2 *= 2;
 1181                                 f1 /= 2;
 1182                         }
 1183                         continue;
 1184                 }
 1185                 if ( fail == 0 )
 1186                         break;
 1187                 
 1188                 if ( f1 < f2 )
 1189                         f2 += fail / f1;
 1190                 else
 1191                         f1 += fail / f2;
 1192 
 1193                 if ( ( f1 > fail ) && ( f2 > fail ) )
 1194                         break;
 1195         } // end-while
 1196 
 1197         if ( f1 < f2 )
 1198         {
 1199                 // f1 und f2 vertauschen
 1200                 long swap= f1;
 1201                 f1= f2;
 1202                 f2= swap;
 1203         }
 1204 
 1205         if ( f1 < ( fail * 2 ) )
 1206                 f2++;
 1207         
 1208         high= ( WORD ) f1;
 1209         low= ( WORD ) f2;
 1210         
 1211         if ( cnt == 0 )
 1212                 MessageBox( GetFocus( ), "Fehler beim Zerlegen !", "Am9513a", MBINFO );
 1213         
 1214         return TRUE;
 1215 }
 1216 
 1217 DWORD TGenericController::GetTicksPerSecond(void)
 1218 {
 1219         return 100000L;
 1220 }
 1221 
 1222 void TGenericController::DigitalOut(BYTE data)
 1223 {
 1224         //Portzugriffe nur über Offsets zum Basisport im Treiber
 1225         Hardware->Write(3,data);
 1226 }
 1227 
 1228 void TGenericController::DigitalIn( BYTE *data )
 1229 {
 1230         //Portzugriffe nur über Offsets zum Basisport im Treiber
 1231         Hardware->Read(2,data);
 1232 }
 1233 
 1234 //ap - neu !!!
 1235 void TGenericController::SetSound(BOOL param)
 1236 {
 1237         Hardware->Write(3, (BYTE)(param?1:0));
 1238 }
 1239 
 1240 BOOL TGenericController::SelectChip( /* BYTE */)
 1241 {
 1242         // Zähler zurücksetzen
 1243         Reset();
 1244         Delay( 50 );
 1245         // Check IO
 1246         ChooseDataPtr( CNT1, CLR );
 1247         WriteData( 0xDAAB );
 1248         ChooseDataPtr( CNT2, CLR );
 1249         WriteData( 0x0000 );
 1250         ChooseDataPtr( CNT1, CLR );
 1251         WORD value= ReadData( );
 1252 
 1253         if ( 0xDAAB != value )
 1254         {
 1255                 char buf[ MaxString ];
 1256                 sprintf( buf, "SelectChip() gab %X zurueck", value );
 1257                 MessageBox( GetFocus( ), buf, "Detector-Fehler Am9513a", MBINFO );
 1258                 return FALSE;
 1259         }
 1260 
 1261         return TRUE;
 1262 }
 1263 
 1264 void TGenericController::ArmC( BYTE counter )
 1265 {
 1266         WriteCmd( counter | 0x20 );
 1267 }
 1268 
 1269 void TGenericController::LoadC( BYTE counter )
 1270 {
 1271         WriteCmd( counter | 0x40 );
 1272 }
 1273 
 1274 void TGenericController::LoadAndArmC( BYTE counter )
 1275 {
 1276         WriteCmd( counter | 0x60 );
 1277 }
 1278 
 1279 void TGenericController::DisarmAndSaveC( BYTE counter )
 1280 {
 1281         WriteCmd( counter | 0x80 );
 1282 }
 1283 
 1284 void TGenericController::LatchToHoldC( BYTE counter )
 1285 {
 1286         WriteCmd( counter | 0xA0 );
 1287 }
 1288 
 1289 void TGenericController::DisarmC( BYTE counter )
 1290 {
 1291         WriteCmd( counter | 0xC0 );
 1292 }
 1293 
 1294 void TGenericController::ClearToggleOut( BYTE counter )
 1295 {
 1296         WriteCmd( counter | 0xE0 );
 1297 }
 1298 
 1299 void TGenericController::SetToggleOut( BYTE counter )
 1300 {
 1301         WriteCmd( counter | 0xE8 );
 1302 }
 1303 
 1304 void TGenericController::Reset( void )
 1305 {
 1306         WriteCmd( 0xFF );
 1307 }
 1308 
 1309 void TGenericController::ChooseDataPtr( BYTE group, BYTE reg )
 1310 {
 1311         // Register adressieren
 1312         WriteCmd( group | reg );
 1313 }
 1314 
 1315 WORD TGenericController::ReadStatus( void )
 1316 {
 1317         Delay( IoWaiTAm9513 );
 1318 
 1319         //Portzugriffe nur über Offsets zum Basisport im Treiber
 1320         BYTE data= 0;
 1321         Hardware->Read(CMD,&data);
 1322         return(data);
 1323 }
 1324 
 1325 void TGenericController::WriteCmd( BYTE cmd )
 1326 {
 1327         if ( nbChipId == DIGITAL )
 1328                 return;
 1329 
 1330         Delay( IoWaiTAm9513 );
 1331 
 1332         //Portzugriffe nur über Offsets zum Basisport im Treiber
 1333         Hardware->Write(CMD,cmd);
 1334 }
 1335 
 1336 void TGenericController::WriteData( WORD daten )
 1337 {
 1338         // Erst niederwertiges, dann hoeherwertiges Byte auf Port addr ausgeben
 1339 
 1340         //Portzugriffe nur über Offsets zum Basisport im Treiber
 1341         Delay(IoWaiTAm9513);
 1342         Hardware->Write(DATA,(BYTE)(daten & 0x00FF));
 1343         Delay(IoWaiTAm9513);
 1344         Hardware->Write(DATA,(BYTE)(((WORD)daten >> 8) & 0x00FF));
 1345         Delay(IoWaiTAm9513);
 1346 }
 1347 
 1348 WORD TGenericController::ReadData( void )
 1349 {
 1350         // Erst niederwertiges, dann hoeherwertiges Byte von Port addr lesen
 1351 
 1352         //Portzugriffe nur über Offsets zum Basisport im Treiber
 1353         BYTE tmpL=0,tmpH=0;
 1354         WORD value= 0;
 1355         
 1356         Delay(IoWaiTAm9513);
 1357         Hardware->Read(DATA,&tmpL);
 1358         Delay(IoWaiTAm9513);
 1359         Hardware->Read(DATA,&tmpH);
 1360         value= tmpH;
 1361         value= value << 8;
 1362         value += tmpL;
 1363         Delay( IoWaiTAm9513 );
 1364         return value;
 1365 }
 1366 
 1367 //##############################################################################
 1368 //******************* Methoden fuer den BraunPSD ******************************
 1369 //##############################################################################
 1370 
 1371 TBraunPsdController::TBraunPsdController(EDeviceType _DeviceID, LPTSTR _HardwareID, DeviceList* Devices) 
 1372                                                 : Controller(_DeviceID,_HardwareID,1), SpecialHardware(0)
 1373 {
 1374         char* szDeviceName= Devices->GetFileName(DeviceID, HardwareID);
 1375         if (!szDeviceName)
 1376         {
 1377                 SpecialHardware= new BraunPsdDummyIo();
 1378                 Hardware= SpecialHardware;
 1379         }
 1380         else
 1381         {
 1382                 SpecialHardware= new BraunPsdIo(szDeviceName);
 1383                 Hardware= SpecialHardware;
 1384         }
 1385 }
 1386 
 1387 TBraunPsdController::~TBraunPsdController()
 1388 {
 1389         _FREEOBJ(Hardware);
 1390 }
 1391 
 1392 BOOL TBraunPsdController::Check()
 1393 {
 1394         //ap - noch zu implementieren!!!
 1395         return TRUE;
 1396 }
 1397 
 1398 BOOL TBraunPsdController::SetTimeout(unsigned long Cycles)
 1399 {
 1400         if (!SpecialHardware)
 1401                 return FALSE;
 1402 
 1403         return (SpecialHardware->SetTimeout(Cycles));
 1404 }
 1405 
 1406 BOOL TBraunPsdController::GetData(IrpParamsGetData *Params) // 31.06.2004 MEMCORRECT (IrpParamsGetData *Params)
 1407 {
 1408         if (!SpecialHardware)
 1409                 return FALSE;
 1410 
 1411         return (SpecialHardware->GetData(Params));
 1412 }
 1413