/*******************************************************************/ /* Compiling: CL/AL /c /G2 /F 1000 p180xmc.c <- for large mode. */ /* Compiling: CL/AH /c /G2 /F 1000 p180xmc.c <- for huge mode. */ /*******************************************************************/ #include "P1602DR.H" /*** 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 P1602_FloatSub2(float fA, float fB) { return(fA-fB); } short P1602_ShortSub2(short nA, short nB) { return(nA-nB); } WORD P1602_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; return( wReturnCode ); } WORD P1602_DriverClose(void) { return( 0 ); } WORD P1602_GetDriverVersion(WORD *wDriverVersion) { *wDriverVersion=0x200; return( NoError ); } /* --------------------------------------------------------------------- */ WORD P1602_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 P1602_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 P1602_WhichBoardActive(void) { return( wActiveBoardNo ); } /* --------------------------------------------------------------------- */ WORD P1602_Hex(WORD *wData) { WORD wVal,wTemp,wTime; DWORD dwTime; float fAMP,fTemp; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* Clear FIFO */ outpw(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outpw(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ outpw((WORD)(wAddrCtrl+4),0x0fff); /* MACH generate a software trigger pulse */ dwTime=0; for (;;) { wVal=inpw(wAddrCtrl)&0x20; if (wVal!=0) break; dwTime++; if (dwTime>6553000) return(AdPollingTimeOut); } (*wData)=(inpw(wAddrAdda))&0xffff; return(0); } /* --------------------------------------------------------------------- */ WORD P1602_Di(WORD *wDi) { if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } *wDi=inpw(wAddrDio)&0xffff; return(NoError); } /* --------------------------------------------------------------------- */ WORD P1602_Do(WORD wDo) { if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } outpw(wAddrDio,wDo); return(NoError); } /* --------------------------------------------------------------------- */ WORD P1602_Da(WORD wDaChannel, WORD wDaVal) { if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } if (wDaChannel==0) /* channel_0 */ { outpw(wAddrAdda,wDaVal); return(NoError); } else if (wDaChannel==1) /* channel_1 */ { outpw((wAddrAdda+4),wDaVal); return(NoError); } else return(DaChannelError); } /* --------------------------------------------------------------------- */ WORD P1602_AdPollingHex(WORD *wData) { WORD wVal,*wTemp,wTime; DWORD dwTime; float fAMP,fTemp; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* Clear FIFO */ outpw(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outpw(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ outpw((WORD)(wAddrCtrl+4),0x0fff); /* MACH generate a software trigger pulse */ dwTime=0; for (;;) { wVal=inpw(wAddrCtrl)&0x20; if (wVal!=0) break; dwTime++; if (dwTime>6553000) return(AdPollingTimeOut); } *wData=inpw(wAddrAdda)&0xffff; return(0); } /*************************************************************************/ WORD P1602_AdPolling(float *fAdVal) { WORD wVal,wTime; DWORD dwTime; float fAMP,fTemp; int iVAL; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* Clear FIFO */ outpw(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outpw(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ outpw((WORD)(wAddrCtrl+4),0x0fff); /* MACH generate a software trigger pulse */ dwTime=0; for (;;) { wVal=inpw(wAddrCtrl)&0x20; if (wVal!=0) break; dwTime++; if (dwTime>6553000) return(AdPollingTimeOut); } switch (wSysConfig) { case 0 : fAMP=10.0; break; case 1 : fAMP=5.0; break; case 2 : fAMP=2.5; break; case 3 : fAMP=1.25; break; } iVAL=inpw(wAddrAdda)&0xffff; (*fAdVal)=(float)iVAL/32768.0*fAMP; return 0; } /* -------------------------------------------------------------------- */ WORD P1602_AdsPolling(float fAdVal[], WORD wNum) { WORD wVal,wData,wTemp; float fAMP,fTemp; WORD i; DWORD dwTime; int iVAL; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* Clear FIFO */ outpw(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outpw(wAddrCtrl,0xA000); /* Bit15=1=no reset FIFO, BIT13=1=not PIC cmd */ for (i=0; i6553000) return(AdPollingTimeOut); } switch (wSysConfig) { case 0 : fAMP=10.0; break; case 1 : fAMP=5.0; break; case 2 : fAMP=2.5; break; case 3 : fAMP=1.25; break; } iVAL=inpw(wAddrAdda)&0xffff; fAdVal[i]=(float)iVAL/32768.0*fAMP; } return(0); } /***-------------------------------------------------------------------***/ WORD P1602_AdsPacer(float fAdVal[], WORD wNum, WORD wSample) { WORD wVal,wTemp; float fAMP,fTemp; WORD i; DWORD dwTime; int iVAL; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* Clear FIFO */ outpw(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outpw(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 : fAMP=10.0; break; case 1 : fAMP=5.0; break; case 2 : fAMP=2.5; break; case 3 : fAMP=1.25; break; } iVAL=inpw(wAddrAdda)&0xffff; fAdVal[i]=(float)iVAL/32768.0*fAMP; } /* end of for loop */ return(0); } /************************* P1602_Card0 ***********************************/ /*** wThreadStatus : 0x01=MagicScan start 0x02=timeout1 0x08=FIFO overflow 0x80=MagicScan OK ***/ /********************* M FUNCTION ************************/ WORD P1602_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,fAdMin,fAdMax,fAMP; DWORD dwII,dwTime; WORD wJJ,wPacer,wTemp; int iVAL; wRetVal=0; if( wActiveBoardNo>=wTotalBoards ) return ExceedBoardNumber; if (wGetAddress==0) { if (GetAddress()!=0) return(FindBoardError); } /* if(wM_FUN_INIT==0) */ { wM_FUN_INIT=1; outpw(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(); outpw(wAddrCtrl,0x6000); outpw(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 : fAMP=10.0; break; case 1 : fAMP=5.0; break; case 2 : fAMP=2.5; break; case 3 : fAMP=1.25; break; default: wRetVal=ConfigCodeError; goto ret_label; } /* delay for settling time */ for (i=0; i<5; i++) { dwTime=0; for (;;) { wVal=inpw(wAddrCtrl)&0x20; if (wVal!=0) break; dwTime++; if (dwTime>100000) { return(TimeOut); } } inpw(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 P1602_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; outpw(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(); outpw(wAddrCtrl,0x6000); outpw(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=inpw(wAddrCtrl)&0x20; if (wVal!=0) break; dwTime++; if (dwTime>100000) { return(TimeOut); } } inpw(wAddrAdda)&0xffff; } /* end of for loop */ 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 : fAMP=10.0; break; case 1 : fAMP=5.0; break; case 2 : fAMP=2.5; break; case 3 : fAMP=1.25; break; default: wRetVal=ConfigCodeError; return(wRetVal); } ChannelParameter[wTotalCh].fAMP=fAMP; 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 */ outpw(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outpw(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); } } inpw(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=inpw(wAddrCtrl)&0x04; if (i!=0) return(0); /* PIC OK */ j++; if (j>32760) return(1); /* time out */ } } /************************* P1602_Card0 **********************************/ WORD P1602_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 */ outpw(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outpw(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); } } inpw(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=inpw(wAddrCtrl)&0x60; if(wVal==0x20) { wX2ThreadStatus=8; disable_timer0(); return FifoOverflow; } if(wVal!=0x60) dwT++; else { wVal=inpw(wAddrAdda)&0xffff; wBuf0[dwX2P1++]=wVal&0xffff; if (dwX2P1>=dwX2Group) { return NoError; } dwT=0; } } ret_label: disable_timer0(); return InvalidateData; } /* -------------------------------------------------------------------- 0 : no data 1 : ready 2 : FIFO overflow */ WORD P1602_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 !!! */ outpw(wAddrCtrl,i); j=0; while ((inpw(wAddrCtrl)&0x04)!=0) { j++; if (j>65530) return(AdControllerError); /* time out */ } outpw(wAddrCtrl,(WORD)(i | 0x2000)); /* set pic high !!! */ j=0; while ((inpw(wAddrCtrl)&0x04)==0) { j++; if (j>65530) return(AdControllerError); /* time out */ } return(0); } /*----------------------------------------------------------------------*/ WORD P1602_SetChannelConfig(WORD wAdChannel, WORD wAdConfig) { WORD wConfig,wChannel; /****************************************/ wChannel = (wAdChannel&0x1f); wSysConfig = (wAdConfig&0x1f); /* store for P1602_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 P1602_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; outpw((wAddrTimer+3*4), 0xb0); /* timer_2 mode_0 0xb0 */ outpw((wAddrTimer+2*4), wLow); outpw((wAddrTimer+2*4), wHigh); fTimeOut=1.0; /* wait 1 to stop */ for( ; ; ) { wVal=inpw(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 */ { outpw((WORD)(wAddrTimer+3*4), 0x34); /* enable timer_0 */ outpw((WORD)(wAddrTimer+0*4), (WORD)(divv & 0xff)); outpw((WORD)(wAddrTimer+0*4), (WORD)((divv>>8) & 0xff)); } void disable_timer0(void) { outpw((WORD)(wAddrTimer+3*4), 0x34); /* disable timer_0 */ outpw((WORD)(wAddrTimer+0*4), 0x01); outpw((WORD)(wAddrTimer+0*4), 0x00); } void disable_timer1(void) /* timer1 for external trigger */ { outpw((WORD)(wAddrTimer+3*4), 0x74); /* disable timer_1 */ outpw((WORD)(wAddrTimer+1*4), 0x01); outpw((WORD)(wAddrTimer+1*4), 0x00); } /*************************************************************** **************** MagicScan Function ************************** ***************************************************************/ WORD P1602_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 P1602_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 */ outpw(wAddrCtrl,0x2000); /* Bit15=0=clear FIFO, Bit13=1=not PIC cmd */ outpw(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; } inpw(wAddrAdda)&0xffff; } dwMagicLowAlarm=0; dwMagicHighAlarm=0; for(i=0; i100000) return TimeOut; } dwMagicSum[j]+=(inpw(wAddrAdda)&0xffff); 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 P1602_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); } /* ---------------------- P1602_SaveScan ------------------------------- */ WORD P1602_SaveScan(WORD wAdChannel, WORD wBuf[]) { if (wAdChannel>=32) return(AdChannelError); wMagicScanSave[wAdChannel]=1; wMagicScanBuf[wAdChannel]=wBuf; return(NoError); } void P1602_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=inpw(0xcfc); DeviceID=inpw(0xcfe); if( VendorID==0x1234 && DeviceID==0x5676 ) { 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); } /******************* Clear Screen *********************/ void clrscr(void) { union REGS r; r.h.ah=6; r.h.al=0; r.h.ch=0; r.h.cl=0; r.h.dh=24; r.h.dl=79; r.h.bh=7; int86(0x10,&r,&r); } void gotoxy(int x,int y) { union REGS r; r.h.ah=2; r.h.dl=x-1; r.h.dh=y-1; r.h.bh=0; int86(0x10,&r,&r); }