/************************************************* * Routines to read the ANL Mutiplexed A/D * * * * GdA 12/6/91 * ************************************************/ #include #include #include #include #include #define BIT32 0x80000000 /* highest bit on */ void anl_adc_init(base, gain_mode, gains, diff_mode) unsigned base; int *gain_mode, *diff_mode, gains[]; /* gain_mode = 1 identical gain words for all channels 0 individual gain words " " " " diff_mode = 1 48 differential input mode 0 96 single-ended input mode gains[] vector containing the 1, 48 or 96 GAIN WORD(s) ( NOT the gain! see manual) Warning: since several modules may be used, the this package does not keep memory of these parameters. It is of responsability of the calling program to keep them. */ { char *addb; unsigned int *addl; unsigned svalue; int i, ev_id, nch; char sem_name[11], dummy[9]; /* automatic generation of the event name ( ad...... ) */ strcpy(sem_name, "ad"); itoa(base, dummy); strncat(sem_name, dummy, strlen(dummy)); /* link/create event */ if ((ev_id = _ev_link(sem_name)) == -1) if ((ev_id = _ev_creat(1, -1, 1, sem_name)) == -1){ exit(_errmsg(errno,"anl_adc_init: error creating event")); } fpermit( base, 0x200); if (_ev_wait(ev_id, 1, 1) == -1){ exit(_errmsg(errno, "anl_adc_init: error waiting for event")); } if( *diff_mode ) addb = ( char *)( base + 0x1ea); /* 48 channel differential */ else addb = ( char *)( base + 0x1eb); /* 96 channel differential */ *addb = 1; if( *gain_mode == 1){ addb = ( char *)( base + 0x1ef); /* enable identical gain */ *addb = 1; addb = ( char *)( base + 0x1e9); /* identical gain */ *addb = (unsigned char) gains[0]; } else if( *gain_mode == 0){ addb = ( char *)( base + 0x1f0); /* enable individual gain */ *addb = 1; nch = 96; if (*diff_mode) nch = 48; addb = ( char *)( base + 0x180); /* write gains */ for ( i = 0; i < nch; i++) *(addb+i) = (unsigned char) gains[i]; } if (_ev_signal(ev_id, 0) == -1) { exit(_errmsg(errno, "anl_adc_init: error signalling event")); } if (_ev_unlink(ev_id) == -1){ exit(_errmsg(errno, "anl_adc_init: error unlinking event")); } /* delete event from system if this was the last process to unlink */ if (_ev_delete(sem_name) == -1 && errno != E_EVBUSY){ exit(_errmsg(errno, "anl_adc_init: error deleting event")); } } void anl_adc_read(base, data, ndata, gain_mode, gains, diff_mode) unsigned base; int *ndata, *diff_mode, *gain_mode, data[], gains[]; { char *addb; unsigned int *addl; char sem_name[11], dummy[9]; int i, ev_id; int nloop; fpermit(base, 0x200); strcpy(sem_name, "ad"); itoa(base, dummy); strncat(sem_name, dummy, strlen(dummy)); /* link/create event */ if ((ev_id = _ev_link(sem_name)) == -1) if ((ev_id = _ev_creat(1, -1, 1, sem_name)) == -1){ exit(_errmsg(errno,"anl_adc_init: error creating event")); } if (_ev_wait(ev_id, 1, 1) == -1){ exit(_errmsg(errno, "anl_adc_init: error waiting for event")); } /* read A/D parameters */ addl = ( unsigned long *) base; data[0] = *addl; if( data[0] & 0x20000000 ) *diff_mode = 1; else *diff_mode = 0; if( data[0] & 0x80000000 ) *gain_mode = 1; else *gain_mode = 0; if (*diff_mode) *ndata = 48; else *ndata =96; /* clear address register and clear update_done flag */ addb = ( char *) (base | 0x1e8); *addb = 0x1; /* start update */ addb = ( char *) (base | 0x1ee); *addb = 0x1; /* wait some time ( value in 256th of a second ) c.a 500 microsec per channel needed */ tsleep( BIT32 + 1 + *ndata/2); /* stop update */ addb = ( char *) (base + 0x1ed); *addb = 0x1; /* check that update of last channel is done */ if ( *( addl + *ndata -1 ) & 0x10000000 == 0){ printf(" update not yet done \n"); exit(0); } /* read data */ for (i = 0; i < *ndata; i++){ data[i] = *(addl+i); gains[i] = (data[i] & 0xf000000) >> 24; data[i] &= 0xfff; } if (_ev_signal(ev_id, 0) == -1) { exit(_errmsg(errno, "anl_adc_init: error signalling event")); } if (_ev_unlink(ev_id) == -1){ exit(_errmsg(errno, "anl_adc_init: error unlinking event")); } /* delete event from system if this was the last process to unlink */ if (_ev_delete(sem_name) == -1 && errno != E_EVBUSY){ exit(_errmsg(errno, "anl_adc_init: error deleting event")); } } int gain_word(gain) int gain; { int code; switch (gain) { case 1: code = 0; break; case 2: code = 0x1; break; case 4: code = 0x2; break; case 8: code = 0x5; break; case 16: code = 0x6; break; case 32: code = 0x8; break; case 64: code = 0x9; break; case 128: code = 0xa; break; case 256: code = 0xc; break; case 512: code = 0xd; break; case 1024: code = 0xe; break; default: code = -1; break; } return code; }