head 4.4; access ; symbols ; locks oasisa:4.4; strict; comment @ * @; 4.4 date 2001.06.19.12.15.37; author oasisa; state Exp; branches ; next ; desc @New Repository; 6/19/2001 (klh) @ 4.4 log @New Repository; 6/19/2001 (klh) @ text @/****************************************************************************/ /* Copyright 1995 MBARI */ /****************************************************************************/ /* $Header: specprr.c,v 1.1 2001/06/19 11:44:57 oasisa Exp $ */ /* Summary : Drivers for PRR type Spectroradiometer on OASIS mooring */ /* Filename : specprr.c */ /* Author : Robert Herlien (rah) */ /* Project : OASIS Mooring */ /* $Revision: 1.1 $ */ /* Created : 02/15/95 from sensors.c */ /* */ /* MBARI provides this documentation and code "as is", with no warranty, */ /* express or implied, of its quality or consistency. It is provided without*/ /* support and without obligation on the part of the Monterey Bay Aquarium */ /* Research Institute to assist in its use, correction, modification, or */ /* enhancement. This information should not be published or distributed to */ /* third parties without specific written permission from MBARI. */ /* */ /****************************************************************************/ /* Modification History: */ /* 15feb95 rah - created from sensors.c */ /* $Log: specprr.c,v $ * Revision 1.1 2001/06/19 11:44:57 11:44:57 oasisa (Oasis users) * Initial revision * * Revision 4.0 98/03/09 11:44:42 11:44:42 bobh (Bob Herlien) * M3 Deployment of March '98, new Sat-Pac driver * * Revision 3.9 97/10/28 13:59:50 13:59:50 bobh (Bob Herlien) * EqPac Deployment of Nov 1997 * * Revision 3.8 97/09/12 10:50:54 10:50:54 bobh (Bob Herlien) * Redeploy M1 * * Revision 3.7 97/07/23 11:18:13 11:18:13 bobh (Bob Herlien) * July '97 M1 deployment, new shutter code * * Revision 3.6 96/10/30 14:00:17 14:00:17 bobh (Bob Herlien) * Release for EqPac, M2 Test Replacement * * Revision 3.5 96/07/17 13:01:32 13:01:32 bobh (Bob Herlien) * July '96 deployment of M2 with ARGOS code * * Revision 3.4 96/06/18 15:24:26 15:24:26 bobh (Bob Herlien) * June '96 deployment of M1 * * Revision 3.1 95/03/09 19:31:01 19:31:01 hebo (Bob Herlien) * March '95 Deployment of M1A * * Revision 3.0 95/02/21 18:42:47 18:42:47 hebo (Bob Herlien) * February '95 Deployment * */ /****************************************************************************/ #include /* MBARI type definitions */ #include /* MBARI constants */ #include /* OASIS controller definitions */ #include /* OASIS I/O definitions */ #include /* Log record definitions */ #include /* ARGOS definition */ #include /* Definitions for PRR spectro */ #include <80C196.h> /* 80196 Register mapping */ #include /* OASIS Multitasking definitions */ #include /* SHUTTER, ARGOS definitions */ /********************************/ /* External Functions */ /********************************/ Extern Void drvLogWords( Driver *dp, Nat16 *samplep, Int16 wrds ); Extern char *drvSerPortAndMalloc( Driver *dp, Nat16 size ); Extern Void drv_ser_release( Driver *dp ); Extern Void drv_pwroff( Driver *dp ); Extern Driver *drvr_find( char *name ); Extern Int16 xgetc_tmout( Nat16 tmout ); Extern Int16 xgetn_tmout( char *s, Int16 len, Nat16 tmout ); Extern Void bzero( void *s, int n ); Extern Void bcopy( const Byte *src, Byte *dst, Nat16 len ); Extern char *tmpMalloc( Nat16 size ); Extern Void tmpFree( char *ptr ); Extern TaskDesc *task_create( Reg Driver *dp, Int16 parm1, Int16 parm2 ); #ifdef SHUTTER Extern Void shutter( MBool open ); #endif #ifdef ARGOS_SPECPRR Extern Void argosPrrSample( PrrData *prrdp, Nat16 chans, Nat16 errs ); #endif /********************************/ /* External Data */ /********************************/ Extern Reg TimeOfDay tod; /* Current time in TimeOfDay format */ Extern Nat16 sync_tmout; /* Timeout for drvSync */ #if ( defined(SHUTTER) && (SHUTTER > 0) ) /************************************************************************/ /* Function : shutter */ /* Purpose : Call the shutter driver to open or shut the shutter(s) */ /* Inputs : Boolean, TRUE to open, FALSE to shut */ /* Outputs : None */ /************************************************************************/ Void shutter( MBool open ) { Driver *dp0, *dp1; Nat16 cnt; if ( (dp0 = drvr_find(SHUTTER_SYNC0)) != DRV_NULL ) { dp0->drv_wakeup = tod; dp0->drv_flags |= DO_SYNC; dp0->drv_usrparm = open; } #if (SHUTTER == 1) else return; for ( cnt = sync_tmout; ((cnt > 0) && (dp0->drv_flags & DO_SYNC)); cnt-- ) task_delay( TICKS_PER_SECOND ); #else if ( (dp1 = drvr_find(SHUTTER_SYNC1)) != DRV_NULL ) { dp1->drv_wakeup = tod; dp1->drv_flags |= DO_SYNC; dp1->drv_usrparm = open; } for ( cnt = sync_tmout; ((cnt > 0) && (((dp0 != DRV_NULL) && (dp0->drv_flags & DO_SYNC)) || ((dp1 != DRV_NULL) && (dp1->drv_flags & DO_SYNC)))); cnt-- ) { task_delay( TICKS_PER_SECOND ); } #endif /* (SHUTTER != 1) */ } /* shutter() */ #endif /* defined(SHUTTER) */ /************************************************************************/ /* Function : get_one_prr */ /* Purpose : Get one message from a PRR-600 Spectro */ /* Inputs : Driver Pointer, number of addresses, buff ptr, accum ptr*/ /* Outputs : Channel address, TMOUT_ERR, or ERROR */ /* Side Effects: Accumulate sample values into PrrAccum structure */ /************************************************************************/ Int16 get_one_prr( Driver *dp, Nat16 naddrs, Byte *prrbuf, PrrAccum *prrAccumP ) { Reg Int16 i, dat; Reg Byte *p; Reg Int32 *lp; Reg Nat16 shft; Nat16 tmout, adr, nchans, nbytes, chksum; Reg PrrAccum *prrp; tmout = dp->drv_parms[TIMEOUT]; do { if ( (chksum = xgetc_tmout(tmout)) == ERROR ) return( ERROR ); adr = chksum - '0'; } while ( adr > naddrs ); if ( (nchans = xgetc_tmout(tmout)) > PRR_CHANS ) return( ERROR ); chksum += nchans; if ( (nbytes = (nchans << 1) + 1) > PRRBUFSIZE ) return( ERROR ); if ( xgetn_tmout((char *)prrbuf, nbytes, tmout) != nbytes ) return( ERROR ); for ( i = nbytes, p = prrbuf; i > 1; i-- ) chksum += *p++; if ( (chksum & 0xff) != *p ) return( ERROR ); prrp = prrAccumP + adr; p = prrbuf; lp = prrp->pa_data; for ( i = 0; i < nchans; i++, lp++ ) { dat = (Nat16)(*p++) << 8; dat |= *p++; if ( (dat & 0x6000) == 0x6000 ) /* Check if overflow */ *lp = -1L; else if ( *lp != -1L ) /* If no overflow */ { shft = 8 - ((dat >> 11) & 0x0c); /* Calc shift from gain bits*/ if ( dat & 0x1000 ) /* Bit 12 is sign bit */ dat |= 0xe000; /* Sign extend if negative*/ else dat &= 0x0fff; /* Mask bits if positive */ *lp += (Int32)dat << shft; } } prrp->pa_nchans = nchans; prrp->pa_samples++; return( adr ); } /* get_one_prr() */ /************************************************************************/ /* Function : specprr_drv */ /* Purpose : Driver for Biospherical PRR-600 Spectroradiometer */ /* Inputs : Driver Pointer */ /* Outputs : None */ /************************************************************************/ Void specprr_drv( Driver *dp ) { Reg Int32 tmp; Reg Nat16 addr, chan, nchans, numLogInts, totChans; Reg Int16 *logp, val; Nat16 samples, errs, totAddrs; Byte *prrbuf; PrrAccum *prraccum; PrrData *prrdata; Reg PrrAccum *prrAcP; Reg PrrData *prrdp; #ifdef SHUTTER shutter( TRUE ); /* Open the shutters */ #endif totAddrs = dp->drv_parms[PARM0]; /* Get number of valid PRR addrs*/ if ( totAddrs > PRR_ADDRS ) totAddrs = PRR_ADDRS; if ( (prrbuf = (Byte *)drvSerPortAndMalloc(dp, PRRBUFSIZE + totAddrs * (sizeof(PrrData) + sizeof(PrrAccum)))) == NULL ) return; prraccum = (PrrAccum *)(prrbuf + PRRBUFSIZE); prrdata = (PrrData *)(prraccum + totAddrs); task_delay( 2 * TICKS_PER_SECOND ); /* Wait 2 seconds */ get_one_prr( dp, totAddrs, prrbuf, prraccum ); /* Throw away first sample*/ /* Zero the data array */ bzero( prraccum, totAddrs * (sizeof(PrrData) + sizeof(PrrAccum)) ); for ( samples = errs = 0; (samples < totAddrs * dp->drv_parms[PARM1]) && (errs < dp->drv_parms[PARM2]); ) { if ( get_one_prr(dp, totAddrs, prrbuf, prraccum) == ERROR ) errs++; else samples++; } drv_pwroff( dp ); /* Turn off spectro power */ drv_ser_release( dp ); /* Release serial port */ /* Average the data, copy to the array of data bufs (prrdata), and */ /* also copy to the log buffer (logp). Note that logp reuses the */ /* serial buffer, and that this buffer *isn't big enough* for the */ /* log record, so we'll end up overwriting the accumulator buffer. */ /* That's OK, because PrrAccum is bigger than the data we're logging*/ /* But it's abnormal and a little dangerous, so it's noted here. */ logp = (Int16 *)prrbuf; /* Initialize log pointer */ *logp++ = PRR_FORMAT; /* Insert format flag */ numLogInts = 1; /* Remember how many ints in log buf*/ for ( addr = totChans = 0, prrAcP = prraccum, prrdp = prrdata; addr < totAddrs; addr++, prrAcP++, prrdp++ ) { /* Loop for all address tags */ nchans = prrAcP->pa_nchans; prrdp->pd_nchans = nchans; *logp++ = nchans; numLogInts += nchans + 1; totChans += nchans; for ( chan = 0; chan < nchans; chan++, logp++ ) { if ( (val = prrAcP->pa_samples) == 0 ) tmp = 0L; else tmp = prrAcP->pa_data[chan] / val; if ( (tmp >= 0x200000L) || (tmp <= -0x200000L) ) val = (Int16)(-1); else if ( (tmp >= 0x20000L) || (tmp <= -0x20000L) ) val = ((Int16)(tmp >> 8) & 0x3fff); else if ( (tmp >= 0x2000) || (tmp <= -0x2000) ) val = ((Int16)(tmp >> 4) & 0x3fff) | 0x4000; else val = ((Int16)tmp & 0x3fff) | 0x8000; prrdp->pd_data[chan] = val; *logp = val; } /* Inner for */ } /* Outer for */ drvLogWords( dp, (Nat16 *)prrbuf, numLogInts ); /* Log the data */ #ifdef ARGOS_SPECPRR argosPrrSample( prrdata, totChans, errs ); /* Store ARGOS data */ #endif tmpFree( (char *)prrbuf ); /* Free the buffer */ #ifdef SHUTTER shutter( FALSE ); /* Close the shutters */ #endif } /* specprr_drv() */ @