#include "P1202DR.H" #pragma inline /*** wBuf0[] -> the scaned data is stored as 0,1,0,1,0,1,0,1,... order |<-DATACOUNT->| |<-DATACOUNT->| wBuf1[] -> the scaned data is stored as 0,0,0,0,.....,0,1,1,1,1,.....,1 order ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ch:0 data ch:1 data ***/ extern WORD wBuf0[]; extern WORD wBuf1[]; /* -------------------------------------------------------------------- */ float P1202_FloatSub2(float fA, float fB) { return(fA-fB); } short P1202_ShortSub2(short nA, short nB) { return(nA-nB); } WORD P1202_DriverInit(WORD *wBoards) { WORD wReturnCode; *wBoards=0; wReturnCode=GetAddress(); if( 0!=wReturnCode || 0==wTotalBoards ) { return( wReturnCode ); } do /*Disable all P1602 timer0 timer1*/ { wAddrTimer = wConfigSpace[*wBoards][0]; disable_timer0(); disable_timer1(); *wBoards = *wBoards + 1; }while(*wBoards < wTotalBoards); wAddrTimer = 0; wReturnCode=pic_control(0xc000); return( wReturnCode ); } WORD P1202_DriverClose(void) { return( 0 ); } WORD P1202_GetDriverVersion(WORD *wDriverVersion) { *wDriverVersion=0x200; return( NoError ); } /* -------------------------------------------------------------------- */ WORD P1202_GetConfigAddressSpace(WORD wBoardNo, WORD *wAddrTimer2, WORD *wAddrCtrl2,WORD *wAddrDio2, WORD *wAddrAdda2) { WORD wIndex; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } if( wBoardNo>=wTotalBoards ) return ExceedBoardNumber; wIndex=wBoardNo; *wAddrTimer2 = wConfigSpace[wIndex][0]; *wAddrCtrl2 = wConfigSpace[wIndex][1]; *wAddrDio2 = wConfigSpace[wIndex][2]; *wAddrAdda2 = wConfigSpace[wIndex][3]; return(NoError); } WORD P1202_ActiveBoard( WORD wBoardNo ) { WORD wReturnCode; if( wBoardNo>=wTotalBoards ) return ExceedBoardNumber; wActiveBoardNo=wBoardNo; /* set the active board */ wAddrTimer = wConfigSpace[wActiveBoardNo][0]; wAddrCtrl = wConfigSpace[wActiveBoardNo][1]; wAddrDio = wConfigSpace[wActiveBoardNo][2]; wAddrAdda = wConfigSpace[wActiveBoardNo][3]; disable_timer0(); wReturnCode=pic_control(0xc000); return(wReturnCode); } WORD P1202_WhichBoardActive(void) { return( wActiveBoardNo ); } /* -------------------------------------------------------------------- */ WORD P1202_Di(WORD *wDi) { if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } *wDi=inport(wAddrDio)&0xffff; return(NoError); } /* -------------------------------------------------------------------- */ WORD P1202_Do(WORD wDo) { if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } outport(wAddrDio,wDo); return(NoError); } /* -------------------------------------------------------------------- */ WORD P1202_Da(WORD wDaChannel, WORD wDaVal) { if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } if (wDaChannel==0) /* channel_0 */ { outport(wAddrAdda,wDaVal); return(NoError); } else if (wDaChannel==1) /* channel_1 */ { outport((wAddrAdda+4),wDaVal); return(NoError); } else return(DaChannelError); } /*********************************************************************/ WORD P1202_AdPolling(float *fAdVal) { WORD wVal,wTemp,wTime; DWORD dwTime; float fMAX,fZERO,fTemp; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* Clear FIFO */ outport(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outport(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ outport((WORD)(wAddrCtrl+4),0xffff); /* MACH generate a software trigger pulse */ dwTime=0; for (;;) { wVal=inport(wAddrCtrl)&0x20; if (wVal!=0) break; dwTime++; if (dwTime>6553000) return(AdPollingTimeOut); } switch (wSysConfig) { case 0 : fZERO=2048.0; fMAX=5.0; break; case 1 : fZERO=2048.0; fMAX=2.5; break; case 2 : fZERO=2048.0; fMAX=1.25; break; case 3 : fZERO=2048.0; fMAX=0.625; break; case 4 : fZERO=2048.0; fMAX=10.0; break; case 5 : fZERO=2048.0; fMAX=5.0; break; case 6 : fZERO=2048.0; fMAX=2.5; break; case 7 : fZERO=2048.0; fMAX=1.25; break; case 8 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 9 : fZERO= 0.0; fMAX=5.0/2.0; break; // Max=4096 case 10: fZERO= 0.0; fMAX=2.5/2.0; break; // Max=4096 case 11: fZERO= 0.0; fMAX=1.25/2.0; break; // Max=4096 case 0x10 : fZERO=2048.0; fMAX=5.0; break; case 0x11 : fZERO=2048.0; fMAX=0.5; break; case 0x12 : fZERO=2048.0; fMAX=0.05; break; case 0x13 : fZERO=2048.0; fMAX=0.005; break; case 0x14 : fZERO=2048.0; fMAX=10.0; break; case 0x15 : fZERO=2048.0; fMAX=1.0; break; case 0x16 : fZERO=2048.0; fMAX=0.1; break; case 0x17 : fZERO=2048.0; fMAX=0.01; break; case 0x18 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 0x19 : fZERO= 0.0; fMAX=1.0/2.0; break; // Max=4096 case 0x1A : fZERO= 0.0; fMAX=0.1/2.0; break; // Max=4096 case 0x1B : fZERO= 0.0; fMAX=0.01/2.0; break; // Max=4096 } wTemp=inport(wAddrAdda)&0x0fff; fTemp=(float)wTemp-fZERO; *fAdVal=(fTemp/2048.0)*fMAX; return(0); } /*----------------------------------------------------------------------*/ WORD P1202_AdsPolling(float fAdVal[], WORD wNum) { WORD wVal,wData; float fMAX,fZERO,fTemp; WORD i; DWORD dwTime; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* Clear FIFO */ outport(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outport(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ for (i=0; i6553000) return(AdPollingTimeOut); } switch (wSysConfig) { case 0 : fZERO=2048.0; fMAX=5.0; break; case 1 : fZERO=2048.0; fMAX=2.5; break; case 2 : fZERO=2048.0; fMAX=1.25; break; case 3 : fZERO=2048.0; fMAX=0.625; break; case 4 : fZERO=2048.0; fMAX=10.0; break; case 5 : fZERO=2048.0; fMAX=5.0; break; case 6 : fZERO=2048.0; fMAX=2.5; break; case 7 : fZERO=2048.0; fMAX=1.25; break; case 8 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 9 : fZERO= 0.0; fMAX=5.0/2.0; break; // Max=4096 case 10: fZERO= 0.0; fMAX=2.5/2.0; break; // Max=4096 case 11: fZERO= 0.0; fMAX=1.25/2.0; break; // Max=4096 case 0x10 : fZERO=2048.0; fMAX=5.0; break; case 0x11 : fZERO=2048.0; fMAX=0.5; break; case 0x12 : fZERO=2048.0; fMAX=0.05; break; case 0x13 : fZERO=2048.0; fMAX=0.005; break; case 0x14 : fZERO=2048.0; fMAX=10.0; break; case 0x15 : fZERO=2048.0; fMAX=1.0; break; case 0x16 : fZERO=2048.0; fMAX=0.1; break; case 0x17 : fZERO=2048.0; fMAX=0.01; break; case 0x18 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 0x19 : fZERO= 0.0; fMAX=1.0/2.0; break; // Max=4096 case 0x1A : fZERO= 0.0; fMAX=0.1/2.0; break; // Max=4096 case 0x1B : fZERO= 0.0; fMAX=0.01/2.0; break; // Max=4096 } wData=inport(wAddrAdda)&0x0fff; fTemp=(float)wData-fZERO; fAdVal[i]=(fTemp/2048.0)*fMAX; } return(0); } /***------------------------------------------------------------***/ WORD P1202_AdsPacer(float fAdVal[], WORD wNum, WORD wSample) { WORD wVal,wTemp; float fMAX,fZERO,fTemp; WORD i; DWORD dwTime; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* Clear FIFO */ outport(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outport(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ enable_timer0(wSample); /* sampling rate=8M/dwSample */ for (i=0; i6553000) return(AdPollingTimeOut); } switch (wSysConfig) { case 0 : fZERO=2048.0; fMAX=5.0; break; case 1 : fZERO=2048.0; fMAX=2.5; break; case 2 : fZERO=2048.0; fMAX=1.25; break; case 3 : fZERO=2048.0; fMAX=0.625; break; case 4 : fZERO=2048.0; fMAX=10.0; break; case 5 : fZERO=2048.0; fMAX=5.0; break; case 6 : fZERO=2048.0; fMAX=2.5; break; case 7 : fZERO=2048.0; fMAX=1.25; break; case 8 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 9 : fZERO= 0.0; fMAX=5.0/2.0; break; // Max=4096 case 10: fZERO= 0.0; fMAX=2.5/2.0; break; // Max=4096 case 11: fZERO= 0.0; fMAX=1.25/2.0; break; // Max=4096 case 0x10 : fZERO=2048.0; fMAX=5.0; break; case 0x11 : fZERO=2048.0; fMAX=0.5; break; case 0x12 : fZERO=2048.0; fMAX=0.05; break; case 0x13 : fZERO=2048.0; fMAX=0.005; break; case 0x14 : fZERO=2048.0; fMAX=10.0; break; case 0x15 : fZERO=2048.0; fMAX=1.0; break; case 0x16 : fZERO=2048.0; fMAX=0.1; break; case 0x17 : fZERO=2048.0; fMAX=0.01; break; case 0x18 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 0x19 : fZERO= 0.0; fMAX=1.0/2.0; break; // Max=4096 case 0x1A : fZERO= 0.0; fMAX=0.1/2.0; break; // Max=4096 case 0x1B : fZERO= 0.0; fMAX=0.01/2.0; break; // Max=4096 } wTemp=inport(wAddrAdda)&0x0fff; fTemp=(float)wTemp-fZERO; fAdVal[i]=(fTemp/2048.0)*fMAX; } return(0); } /************************* P1202_Card0 **********************************/ /*** wThreadStatus : 0x01=MagicScan start 0x02=timeout1 0x08=FIFO overflow 0x80=MagicScan OK ***/ /********************* M FUNCTION ************************/ WORD P1202_M_FUN_1(WORD wDaFrequency, WORD wDaWave, float fDaAmplitude, WORD wAdClock, WORD wAdNumber, WORD wAdConfig, float fAdBuf[], float fLowAlarm, float fHighAlarm) { double f1,f2,f; DWORD dwRet,dwOutput,dwOutputs[20],dwI,dwJ; unsigned char status; WORD i,j,k,ii,iii,wRetVal,wInputs[20],wII1,wII2,wVal,wConfig; WORD wData,wI,wJ; double pi2,ff,dfVal; float fVal,fVal2,fTemp,fMAX,fAdMin,fAdMax,fZERO; DWORD dwII,dwTime; WORD wJJ,wPacer; wRetVal=0; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* if(wM_FUN_INIT==0) */ { wM_FUN_INIT=1; outport(wAddrCtrl,0xffff); /* reset pic */ wVal=wait_until_pic_ok(); /* wait until pic ok */ if(wVal!=0) {wRetVal=AdControllerError; goto ret_label;} wVal=pic_control(0xc000); /* force pic go to power-on state */ if (wVal!=0) {wRetVal=AdControllerError; goto ret_label;} } if (wDaFrequency!=WDaFrequency) goto compute_start; if (fDaAmplitude!=FDaAmplitude) goto compute_start; goto compute_end; compute_start: pi2=3.1415926535*2.0/(float)wDaFrequency; ff=(fDaAmplitude/10.0)*2047.0; f1=0.0; for (wI=0; wI=0) { j=(int)((f2/1.0)*ff); j=0x800+j; /* 0x800=2048 */ } else { j=(int)((f2/(-1.0)*ff)); j=0x800-j; /* 0x800=2048 */ } f1+=pi2; wBuf0[wI]=j; } WDaFrequency=wDaFrequency; FDaAmplitude=fDaAmplitude; compute_end: disable_timer0(); disable_timer1(); outport(wAddrCtrl,0x6000); outport(wAddrCtrl,0xE000); /* reset fifo */ wPacer = (WORD) wAdClock; wConfig= (WORD) wAdConfig; wConfig&= 0x1f; wConfig= wConfig << 6; wConfig+= 0x8400; wVal=pic_control(wConfig); /* 1010 0100 0000 0000-->load chan_1,PGA=1 */ if (wVal!=0) {wRetVal=AdControllerError; goto ret_label;} enable_timer0(wPacer); /* --> start AD --> 330K */ for(wI=0; wI stop AD */ switch (wAdConfig) { case 0 : fZERO=2048.0; fMAX=5.0; break; case 1 : fZERO=2048.0; fMAX=2.5; break; case 2 : fZERO=2048.0; fMAX=1.25; break; case 3 : fZERO=2048.0; fMAX=0.625; break; case 4 : fZERO=2048.0; fMAX=10.0; break; case 5 : fZERO=2048.0; fMAX=5.0; break; case 6 : fZERO=2048.0; fMAX=2.5; break; case 7 : fZERO=2048.0; fMAX=1.25; break; case 8 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 9 : fZERO= 0.0; fMAX=5.0/2.0; break; // Max=4096 case 10: fZERO= 0.0; fMAX=2.5/2.0; break; // Max=4096 case 11: fZERO= 0.0; fMAX=1.25/2.0; break; // Max=4096 case 0x10 : fZERO=2048.0; fMAX=5.0; break; case 0x11 : fZERO=2048.0; fMAX=0.5; break; case 0x12 : fZERO=2048.0; fMAX=0.05; break; case 0x13 : fZERO=2048.0; fMAX=0.005; break; case 0x14 : fZERO=2048.0; fMAX=10.0; break; case 0x15 : fZERO=2048.0; fMAX=1.0; break; case 0x16 : fZERO=2048.0; fMAX=0.1; break; case 0x17 : fZERO=2048.0; fMAX=0.01; break; case 0x18 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 0x19 : fZERO= 0.0; fMAX=1.0/2.0; break; // Max=4096 case 0x1A : fZERO= 0.0; fMAX=0.1/2.0; break; // Max=4096 case 0x1B : fZERO= 0.0; fMAX=0.01/2.0; break; // Max=4096 default: wRetVal=ConfigCodeError; goto ret_label; } // delay for settling time for (i=0; i<5; i++) { dwTime=0; for (;;) { wVal=inport(wAddrCtrl)&0x20; if (wVal!=0) break; dwTime++; if (dwTime>100000) { return(TimeOut); } } inport(wAddrAdda)&0xffff; } fAdMin=10.0; fAdMax=-10.0; for(i=0; ifAdMax) fAdMax=fVal; fAdBuf[i]=fVal; } ret_label: if (fAdMinfHighAlarm) wRetVal=HighAlarm; return(wRetVal); } /* -------------------------------------------------------------------- */ WORD P1202_M_FUN_2(WORD wDaNumber, WORD wDaWave, WORD wDaBuf[], WORD wAdClock, WORD wAdNumber, WORD wAdConfig, WORD wAdBuf[]) { DWORD dwRet,dwOutput, dwOutputs[20],dwI,dwJ,dwTime; unsigned char status; WORD i,wBase,wII1,wII2,wInputs[20],wConfig,wRetVal,wVal,wData; wRetVal=0; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } { wM_FUN_INIT=1; outport(wAddrCtrl,0xffff); /* reset pic */ wVal=wait_until_pic_ok(); /* wait until pic ok */ if(wVal!=0) {wRetVal=AdControllerError; goto ret_label;} wVal=pic_control(0xc000); /* force pic go to power-on state */ if (wVal!=0) {wRetVal=AdControllerError; goto ret_label;} } disable_timer0(); disable_timer1(); outport(wAddrCtrl,0x6000); outport(wAddrCtrl,0xE000); /* reset fifo */ wConfig=(wAdConfig); wConfig&= 0x1f; wConfig= wConfig << 6; wConfig+= 0x8400; wVal=pic_control(wConfig); /* 1010 0100 0000 0000-->load chan_1,PGA=1 */ if (wVal!=0) {wRetVal=AdControllerError; goto ret_label;} enable_timer0( wAdClock ); /* --> start AD --> 330K */ for (dwI=0; dwI stop AD */ // delay for settling time for (i=0; i<5; i++) { dwTime=0; for (;;) { wVal=inport(wAddrCtrl)&0x20; if (wVal!=0) break; dwTime++; if (dwTime>100000) { return(TimeOut); } } inport(wAddrAdda)&0xffff; } for (i=0; i=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } wTotalCh=0; /* if(wM_FUN_INIT==0) */ { wM_FUN_INIT=1; /* STEP_1 : clear_scan_first */ disable_timer0(); wVal=pic_control(0xC000); /* 11?0 00?? ???? ???? cmd_000=reset */ if(wVal!=0) return(wVal); /* STEP_2 : add_to_scan */ wTotalCh=0; for(i=0; i<32; i++) { if(wChannelStatus[i]!=0) { switch (wAdConfig[i]) { case 0 : fZERO=2048.0; fMAX=5.0; break; case 1 : fZERO=2048.0; fMAX=2.5; break; case 2 : fZERO=2048.0; fMAX=1.25; break; case 3 : fZERO=2048.0; fMAX=0.625; break; case 4 : fZERO=2048.0; fMAX=10.0; break; case 5 : fZERO=2048.0; fMAX=5.0; break; case 6 : fZERO=2048.0; fMAX=2.5; break; case 7 : fZERO=2048.0; fMAX=1.25; break; case 8 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 9 : fZERO= 0.0; fMAX=5.0/2.0; break; // Max=4096 case 10: fZERO= 0.0; fMAX=2.5/2.0; break; // Max=4096 case 11: fZERO= 0.0; fMAX=1.25/2.0; break; // Max=4096 case 0x10 : fZERO=2048.0; fMAX=5.0; break; case 0x11 : fZERO=2048.0; fMAX=0.5; break; case 0x12 : fZERO=2048.0; fMAX=0.05; break; case 0x13 : fZERO=2048.0; fMAX=0.005; break; case 0x14 : fZERO=2048.0; fMAX=10.0; break; case 0x15 : fZERO=2048.0; fMAX=1.0; break; case 0x16 : fZERO=2048.0; fMAX=0.1; break; case 0x17 : fZERO=2048.0; fMAX=0.01; break; case 0x18 : fZERO= 0.0; fMAX=10.0/2.0; break; // Max=4096 case 0x19 : fZERO= 0.0; fMAX=1.0/2.0; break; // Max=4096 case 0x1A : fZERO= 0.0; fMAX=0.1/2.0; break; // Max=4096 case 0x1B : fZERO= 0.0; fMAX=0.01/2.0; break; // Max=4096 default: wRetVal=ConfigCodeError; return(wRetVal); } ChannelParameter[wTotalCh].fZERO=fZERO; ChannelParameter[wTotalCh].fMAX=fMAX; wConfig = (wAdConfig[i])&0x0f; wConfig = wConfig << 6; wConfig += i; wConfig+= 0xD000; /* this is set channel config command */ wVal=pic_control(wConfig); if(wVal!=0) return(wVal); wTotalCh++; } } } if (wDaFrequency!=WDaFrequency) goto compute_start; if (fDaAmplitude!=FDaAmplitude) goto compute_start; goto compute_end; compute_start: pi2=3.1415926535*2.0/(float) wDaFrequency; ff=(fDaAmplitude/10.0)*2047.0; f1=0.0; for (wI=0; wI=0) { j=(int)((f2/1.0)*ff); j=0x800+j; /* 0x800=2048 */ } else { j=(int)((f2/(-1.0)*ff)); j=0x800-j; /* 0x800=2048 */ } f1+=pi2; wBuf0[dwI]=j; } WDaFrequency=wDaFrequency; FDaAmplitude=fDaAmplitude; compute_end: disable_timer0(); disable_timer1(); /* STEP_3 : start_to_scan */ wVal=pic_control(0xD400); /* 11?1 01?? ???? ???? cmd_101=start scan */ if (wVal!=0) return(wVal); /* Clear FIFO */ outport(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outport(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ enable_timer0(wAdClock); /* --> start AD --> 330K */ for (wI=0; wI stop AD */ for (i=0; i100000) { return(TimeOut); } } inport(wAddrAdda)&0xffff; } fAdMin=10.0; fAdMax=-10.0; for (i=0; ifAdMax) fAdMax=fVal; fAdBuf[dwIndex+i]=fVal; } } if (fAdMinfHighAlarm) wRetVal=HighAlarm; return(wRetVal); } /* -------------------------------------------------------------------- */ WORD wait_until_pic_ok() { WORD i,j; j=0; for (;;) { i=inport(wAddrCtrl)&0x04; if (i!=0) return(0); /* PIC OK */ j++; if (j>32760) return(1); /* time out */ } } /************************* P1202_Card0 **********************************/ WORD P1202_Card0_StartScan(WORD wSampleRate, WORD wChannelStatus[], WORD wChannelConfig[], WORD wDataCount) { WORD wVal,i,wConfig,wRet; DWORD dwTime; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* STEP_1 : clear_scan_first */ disable_timer0(); wX2Total=0; wVal=pic_control(0xC000); /* 11?0 00?? ???? ???? cmd_000=reset */ if(wVal!=0) return(wVal); /* STEP_2 : add_to_scan */ for(i=0; i<32; i++) { if(wChannelStatus[i]!=0) { wX2Total++; wConfig = (wChannelConfig[i])&0x0f; wConfig = wConfig << 6; wConfig += i; wConfig+= 0xD000; /* this is set channel config command */ wVal=pic_control(wConfig); if(wVal!=0) return(wVal); } } /* STEP_3 : start_to_scan */ wVal=pic_control(0xD400); /* 11?1 01?? ???? ???? cmd_101=start scan */ if (wVal!=0) return(wVal); /* Clear FIFO */ outport(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outport(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ dwX2P1=0; wX2Count= wDataCount; dwX2Group=(DWORD)(wX2Total*wDataCount); if(dwX2Group>9000) return(InvalidateData); wX2Stop=0; enable_timer0(wSampleRate); /* Sampling rate=8M/dwSample */ for (i=0; i100000) { return(TimeOut); } } inport(wAddrAdda)&0xffff; } return( NoError ); } /***---------------------------------------------------------------------- // wThreadStatus : 0x01=MagicScan start // 0x02=timeout 0x08=FIFO overflow ***/ WORD ReadingData() { WORD wVal; DWORD dwT; dwT=0; dwX2P1=0; for(;;) { if (dwT>600000) { wX2ThreadStatus=2; disable_timer0(); return TimeOut; } wVal=inport(wAddrCtrl)&0x60; if(wVal==0x20) { wX2ThreadStatus=8; disable_timer0(); return FifoOverflow; } if(wVal!=0x60) dwT++; else { wVal=inport(wAddrAdda)&0xffff; wBuf0[dwX2P1++]=wVal&0x0fff; if (dwX2P1>=dwX2Group) { return NoError; } dwT=0; } } ret_label: disable_timer0(); return InvalidateData; } /* -------------------------------------------------------------------- 0 : no data 1 : ready 2 : FIFO overflow */ WORD P1202_Card0_ReadData() { WORD i,wVal,j,wIndex; DWORD dwP,dwPP; DWORD dwRetVal; dwRetVal=ReadingData(); if( dwRetVal ) return( dwRetVal); dwPP=0; for(j=0; j65530) return(AdControllerError); /* time out */ } i = i & 0xDFFF; /* set pic low !!! */ outport(wAddrCtrl,i); j=0; while ((inport(wAddrCtrl)&0x04)!=0) { j++; if (j>65530) return(AdControllerError); /* time out */ } outport(wAddrCtrl,(WORD)(i | 0x2000)); /* set pic high !!! */ j=0; while ((inport(wAddrCtrl)&0x04)==0) { j++; if (j>65530) return(AdControllerError); /* time out */ } return(0); } /*----------------------------------------------------------------------*/ WORD P1202_SetChannelConfig(WORD wAdChannel, WORD wAdConfig) { WORD wConfig,wChannel; /****************************************/ wChannel = (wAdChannel&0x1f); wSysConfig = (wAdConfig&0x1f); /* store for P1802_AdPolling */ wConfig = (wAdConfig&0x0f); wConfig = wConfig << 6; wConfig += wChannel; /* Bit15=1 --> no reset FIFO Bit14=? Bit13=? Bit12=0 --> command [001] --> set channel&Config Bit11=0 Bit10=1 Bit9 =B --> Range control code [BB] --> unipolar/bipolar & divided by 2 Bit8 =B Bit7 =B --> gain control code [BB] --> 1/10/100/1000 or 1/2/4/8 Bit6 =B Bit5 =? Bit4-Bit0 --> channel number */ wConfig+= 0x8400; /* this is set channel config command */ return(pic_control(wConfig)); } /* -------------------------------------------------------------------- */ /* address of timer 2 = wAddrTimer+2*4 address of ctrl = wAddrTimer+3*4 input clock = 8M down count 8 time = 1 us down count 65536/8 = 8192 uS --> max 8191 uS */ WORD P1202_DelayUs(WORD wDelayUs) { WORD wDownCount,wLow,wHigh,wVal; double fTimeOut; if (wDelayUs>=8191) return(InvalidateDelay); wDownCount=wDelayUs*8; wLow=wDownCount&0xff; wHigh=(wDownCount>>8)&0xff; outport((wAddrTimer+3*4), 0xb0); /* timer_2 mode_0 0xb0 */ outport((wAddrTimer+2*4), wLow); outport((wAddrTimer+2*4), wHigh); fTimeOut=1.0; /* wait 1 to stop */ for( ; ; ) { wVal=inport(wAddrCtrl)&0x01; if (wVal!=0) return(NoError); fTimeOut+=1.0; if (fTimeOut>6553500.0) return(TimeOut); } } /***---------------------------------------------------------------------- // timer0 --> for pacer trigger // timer1 --> for external trigger // timer2 --> for machine independent timer ***/ void enable_timer0(WORD divv) /* for pacer trigger */ { outport((WORD)(wAddrTimer+3*4), 0x34); /* enable timer_0 */ outport((WORD)(wAddrTimer+0*4), (WORD)(divv & 0xff)); outport((WORD)(wAddrTimer+0*4), (WORD)((divv>>8) & 0xff)); } void disable_timer0(void) { outport((WORD)(wAddrTimer+3*4), 0x34); /* disable timer_0 */ outport((WORD)(wAddrTimer+0*4), 0x01); outport((WORD)(wAddrTimer+0*4), 0x00); } void disable_timer1(void) /* timer1 for external trigger */ { outport((WORD)(wAddrTimer+3*4), 0x74); /* disable timer_1 */ outport((WORD)(wAddrTimer+1*4), 0x01); outport((WORD)(wAddrTimer+1*4), 0x00); } /*************************************************************** **************** MagicScan Function ************************** ***************************************************************/ WORD P1202_ClearScan(void) { WORD i; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } wMP=0; /* driver pointer */ for(i=0; i<32; i++) wMagicScanSave[i]=0; disable_timer0(); return(pic_control(0xC000)); /* 11?0 00?? ???? ???? cmd_000=reset */ } /**----------------------------------------------------------------------**/ WORD P1202_StartScan(WORD wSampleRate, WORD wNum) { WORD wVal; WORD wRetVal; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } wMagicNum=wNum; disable_timer0(); wRetVal=pic_control(0xD400); /* 11?1 01?? ???? ???? cmd_101=start scan */ if (wRetVal!=0) return(wVal); /* Clear FIFO */ outport(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outport(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ enable_timer0(wSampleRate); /* Sampling rate=8M/dwSample */ wVal=magic_scan(); return(wVal); } /***------------------------------------------------------------------- // wThreadStatus : 0x01=MagicScan start // 0x02=timeout1 // 0x04=timeout2 // 0x08=FIFO overflow // 0x80=MagicScan OK ***/ WORD magic_scan() { WORD wVal,w1,w3; DWORD i,dwTime,j,k,dwIndex; for (j=0; j100000) return TimeOut; } inport(wAddrAdda)&0xffff; } dwMagicLowAlarm=0; dwMagicHighAlarm=0; for(i=0; i100000) return TimeOut; } dwMagicSum[j]+=(inport(wAddrAdda)&0x0fff); wMagicNow[j]--; w1=wMagicNow[j]; if (w1==0) { wVal=(WORD)(dwMagicSum[j]/wMagicAve[j]); if (wMagicScanSave[j]==1) { *((wMagicScanBuf[j])+wMagicP[j])=wVal; wMagicP[j]++; } w3=wMagicAlarmType[j]; if(w3>0) /* 0 = no alarm */ { dwIndex=0x01; k=j; while (k>0) { dwIndex=dwIndex<<1; k--; } if (w3==2) /* 2 = low alarm */ { if (wValwMagicHighAlarm[j]) dwMagicHighAlarm |= dwIndex; } else if (w3==4) /* 4 = high or low alarm */ { if (wValwMagicHighAlarm[j]) dwMagicHighAlarm |= dwIndex; } else if (w3==3) /* 3 = in [low,high] alarm */ { if ((wVal>wMagicLowAlarm[j])&& (wVal=5) return(AlarmTypeError); wMagicLowAlarm[wMP]=wLowAlarm; wMagicHighAlarm[wMP]=wHighAlarm; wMagicAlarmType[wMP]=wAlarmType; wChannel = wAdChannel&0x1f; wMagicChannel[wMP]=wChannel; wSysConfig = wAdConfig&0x1f; /* store for P1202_AdPolling */ wMagicConfig[wMP]=wSysConfig; wMagicAve[wMP]=wAverage; wConfig = wAdConfig&0x0f; wConfig = wConfig << 6; wConfig += wChannel; /* Bit15=1 --> no reset FIFO Bit14=1 Bit13=? Bit12=1 --> command [100] --> set channel&Config Bit11=0 Bit10=0 Bit9 =B --> Range control code [BB] --> unipolar/bipolar & divided by 2 Bit8 =B Bit7 =B --> gain control code [BB] --> 1/10/100/1000 or 1/2/4/8 Bit6 =B Bit5 =? Bit4-Bit0 --> channel number */ wConfig+= 0xD000; /* this is set channel config command */ wRetVal=pic_control(wConfig); if (wRetVal!=0) return(wRetVal); wMP++; return(NoError); } /*------------------------------------------------------------*/ WORD P1202_SaveScan(WORD wAdChannel, WORD wBuf[]) { if (wAdChannel>=32) return(AdChannelError); wMagicScanSave[wAdChannel]=1; wMagicScanBuf[wAdChannel]=wBuf; return(NoError); } void P1202_ReadMagicScanResult(DWORD *dwHiAlarm, DWORD *dwLoAlarm) { *dwHiAlarm=dwMagicHighAlarm; *dwLoAlarm=dwMagicLowAlarm; } /**************************************************************/ /* Reading PCI card's configuration address space */ /**************************************************************/ WORD GetAddress(void) { DWORD dConfigAddress,dBaseAddress; WORD HiWord,LoWord; WORD ReturnCode; UCHAR Bus,Device,Function,WhichLong; WORD VendorID,DeviceID; WORD wIrqNumber; wTotalBoards=0; /* initial board number is 0 */ Bus=0; for(Bus=0; Bus<32; Bus++) { Function=0; WhichLong=1; for(Device=0; Device<32; Device++) { WhichLong=0; WriteAddress(Bus,Device,Function,WhichLong); VendorID=inport(0xcfc); DeviceID=inport(0xcfe); if( VendorID==0x1234 && DeviceID==0x5672 ) { WhichLong=4; WriteAddress(Bus,Device,Function,WhichLong); dBaseAddress=_inpd(0xcfc); /*** The Timer Address We Want ***/ WhichLong=5; WriteAddress(Bus,Device,Function,WhichLong); dBaseAddress=_inpd(0xcfc); wAddrTimer=(WORD)(dBaseAddress&0xfffe); wConfigSpace[wTotalBoards][0]=wAddrTimer; /*** The Control Address We Want ***/ WhichLong=6; WriteAddress(Bus,Device,Function,WhichLong); dBaseAddress=_inpd(0xcfc); wAddrCtrl=(WORD)(dBaseAddress&0xfffe); wConfigSpace[wTotalBoards][1]=wAddrCtrl; /** The DIO Address We Want ***/ WhichLong=7; WriteAddress(Bus,Device,Function,WhichLong); dBaseAddress=_inpd(0xcfc); wAddrDio=(WORD)(dBaseAddress&0xfffe); wConfigSpace[wTotalBoards][2]=wAddrDio; /*** The ADDA address we want ***/ WhichLong=8; WriteAddress(Bus,Device,Function,WhichLong); dBaseAddress=_inpd(0xcfc); wAddrAdda=(WORD)(dBaseAddress&0xfffe); wConfigSpace[wTotalBoards][3]=wAddrAdda; WhichLong=9; WriteAddress(Bus,Device,Function,WhichLong); dBaseAddress=_inpd(0xcfc); /*** Getting the IRQ number ***/ wTotalBoards++; /* increment board number */ wGetAddress=1; } } } if( wTotalBoards>16 ) return( NotFoundBoard ); else return( NoError ); } void WriteAddress(UCHAR bBus, UCHAR bDevice, UCHAR bFunction, UCHAR bWhichLong) { DWORD dOutData; WORD HiWord,LoWord; UCHAR HiByte,LoByte; HiWord=0x8000|bBus; HiByte=(bDevice<<3)|bFunction; LoByte=(bWhichLong<<2) & 0xfc; LoWord=( (WORD)HiByte<<8 )|LoByte; dOutData=( (DWORD)HiWord<<16 ) | LoWord; _outpd(0xcf8,dOutData); }