📄 par4ch.c
字号:
IOCTL_PAR4CH_STOP,
&dummy,
sizeof(int),
NULL,
0
);
}
/* PAR4CH FIFO FUNCTIONS:
Par4chReady returns 1 if there is ANY data in the FIFO and 0 if the
FIFO is completely empty. Typically, a return of 1 means that at
least one data point is ready to read.
Note that for requested sampling rates below about 40Hz, the native
averaging capabilities of the A/D chip are exceeded and the kernel
driver does some additional averaging. In this situation,
Par4chReady returning 1 indicates that one native data point and not
a complete averaged data point is ready. To handle this, just check
the return value from Par4chReadData as it will return 0 until it has
read a finished, completely averaged, data point.
Par4chOverflow returns 1 if the FIFO has overflowed and 0 otherwise.
Once overflow occurs, any additional data stored in the FIFO would be
misaligned. So the overflow value is latched and no more data is
saved. The valid data already in the FIFO can still be read out with
PAR4chReadData. When you are ready to continue acquiring new data,
just call Par4chClose, Par4chOpen, and Par4chStart. This will reset
the FIFO and clear the overflow value so that data is saved and
Par4chOverflow again returns 0.
The hardware FIFO has 4 Meg of 4-bit words or 2 Mbytes. It is shared
among 4 channels giving 0x80000 bytes/channel. Each 24 bit sample
takes 3 bytes giving 0x2AAAA samples per channel in the hardware
FIFO. So, it may take a long time before the FIFO overflows.
*/
FUNCTYPE( int ) Par4chReady( DEVHANDLE Par4chHandle ) {
int fifostatus;
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_READY,
NULL,
0,
&fifostatus,
sizeof(int)
);
return( fifostatus );
}
FUNCTYPE( int ) Par4chOverflow( DEVHANDLE Par4chHandle ) {
int fifostatus;
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_OVERFLOW,
NULL,
0,
&fifostatus,
sizeof(int)
);
return( fifostatus );
}
FUNCTYPE( unsigned int ) Par4chReadData(
DEVHANDLE Par4chHandle,
long *Values,
unsigned int Nvalues,
int *Error
) {
int Result, Health, Failure;
long SaveReadError;
unsigned long BytesRead, BytesToRead;
Par4chLastDriverError = 0L;
BytesToRead = Nvalues * sizeof(long);
// Verify that device driver is valid (open).
if (Par4chHandle == BAD_DEVHANDLE) {
Par4chLastDriverError = ERROR_SERVICE_DISABLED;
if (Error)
*Error = PAR4CH_ERROR_DRIVER_NOT_OPEN;
return( 0 );
}
// Verify the health of the PAR4CH.
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_CHECK_HEALTH,
NULL,
0,
&Health,
sizeof(int)
);
if ( Health & HEALTH_VOLTAGE_BAD )
Failure = PAR4CH_ERROR_VOLTAGE_BAD_OFF;
else if ( Health & HEALTH_OVERFLOW )
Failure = PAR4CH_ERROR_OVERFLOW;
else
Failure = PAR4CH_ERROR_NONE;
if ( Failure != PAR4CH_ERROR_NONE ) {
if (Error)
*Error = Failure;
return( 0 );
}
// Read from device, saving result and possible driver error.
Result = OsDriverRead(
Par4chHandle, // Handle to device
Values, // Buffer to receive data
BytesToRead, // Number of bytes to read
&BytesRead // Bytes read
);
SaveReadError = OsGetLastError();
Nvalues = BytesRead / sizeof( long );
// If the read failed, set the failure code in a prioritized manner.
// Bad voltage, FIFO overflow, Driver FIFO sanity, Driver unknown.
if (!Result) {
Nvalues = 0;
// Wait a while, allowing any power down to stabilize.
SrSleep( 30 ); // ms
// Query the health of the PAR4CH.
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_CHECK_HEALTH,
NULL,
0,
&Health,
sizeof(int)
);
// Restore the read error.
Par4chLastDriverError = SaveReadError;
// Set prioritized failure code.
if ( Health & HEALTH_VOLTAGE_BAD )
Failure = PAR4CH_ERROR_VOLTAGE_BAD_OFF;
else if ( Health & HEALTH_OVERFLOW )
Failure = PAR4CH_ERROR_OVERFLOW;
else if (Par4chLastDriverError == ERROR_CRC)
Failure = PAR4CH_ERROR_FIFO_SANITY;
else
Failure = PAR4CH_ERROR_DRIVER_REQUEST_FAILED;
}
else
Failure = PAR4CH_ERROR_NONE;
// Set error parameter if user provided it.
if ( Error )
*Error = Failure;
return( Nvalues ); // # of longs just read or 0 for error
}
/* PAR4CH FRONT PANEL USER LED AND DIGITAL IO:
These functions program the PAR4CH yellow user led and digital IO.
Par4chOpen must be called before these to initialize the PC
parallel port.
*/
FUNCTYPE( void ) Par4chUserLed( DEVHANDLE Par4chHandle, int State ) {
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_USER_LED,
&State,
sizeof(int),
NULL,
0
);
}
FUNCTYPE( void ) Par4chUserIoRd( DEVHANDLE Par4chHandle, int *Value ) {
// Read the PAR4CH user digital input.
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_DIO_READ,
NULL,
0,
Value,
sizeof(int)
);
}
FUNCTYPE( void ) Par4chUserIoWr( DEVHANDLE Par4chHandle, int Value ) {
// Write to the PAR4CH user digital output.
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_DIO_WRITE,
&Value,
sizeof(int),
NULL,
0
);
}
/* PAR4CH PC INTERRUPT:
These functions program the PC interrupt.
Par4chOpen must be called before these to initialize the PC
parallel port.
*/
FUNCTYPE( void ) Par4chInterruptEnable( DEVHANDLE Par4chHandle ) {
int dummy;
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_INTR_ENABLE,
&dummy,
sizeof(int),
NULL,
0
);
}
FUNCTYPE( void ) Par4chInterruptDisable( DEVHANDLE Par4chHandle ) {
int dummy;
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_INTR_DISABLE,
&dummy,
sizeof(int),
NULL,
0
);
}
/* PAR4CH VOLTAGE CHECK FUNCTION:
This function checks the PAR4CH board voltage level. If the voltage is
good, this function returns 1. Otherwise, 0.
NOTE: This function will NOT work until Par4chOpen is called ...
*/
FUNCTYPE( int ) Par4chVoltageGood( DEVHANDLE Par4chHandle ) {
int Val;
DevIoReadWrite(
Par4chHandle,
IOCTL_PAR4CH_VOLTAGE_GOOD,
NULL,
0,
&Val,
sizeof(int)
);
return( Val );
}
/* GENERIC HELPER FUNCTIONS - compensate for differences between OS's
Most of these functions are just wrappers around their OS specific
counterparts defined in the OS section above.
SrKeyboardNonBlock ensures non-blocking mode is enabled, allowing
SrGetKeyCheck to return even if a key has not been pressed.
SrGetKeyWait and SrGetKeyCheck are handy shortcuts for the two
keyboard behaviors OsGetKey provides. If wait is true, OsGetKey
waits until a character is ready and then return it. Otherwise, it
checks for an available character. If one is there, it is read and
returned. Otherwise, EOF is returned.
SrFlushPrint ensures that the last printf string is displayed, even
if it didn't end with a new line (\n) character.
SrSleep puts the calling program to sleep for the specified number of
milliseconds.
SrFileLength returns the length of the specified file in bytes.
*/
FUNCTYPE( int ) SrKeyboardNonBlock( void ) { return( OsSetNonBlock( 1 ) ); }
FUNCTYPE( int ) SrGetKeyCheck( void ) { return( OsGetKey( 0 ) ); }
FUNCTYPE( int ) SrGetKeyWait( void ) { return( OsGetKey( 1 ) ); }
FUNCTYPE( void ) SrFlushPrint( void ) { OsFlushPrint(); }
FUNCTYPE( int ) SrSleep( int ms ) { return( OsSleep( ms, 0 ) ); }
FUNCTYPE( int ) SrWait( int ms ) { return( OsSleep( ms, 1 ) ); }
FUNCTYPE( int ) SrCommit( int fh ) { return( OsCommit( fh ) ); }
#if !defined F_OK
#define F_OK 0x00
#endif
FUNCTYPE( int ) SrFileExist( char *FileName ) {
return( access( FileName, F_OK ) );
}
FUNCTYPE( int ) SrFileLength( int fh ) {
struct stat buffer;
if ( fstat( fh, &buffer ) == -1 ) {
printf( "Could not get file stats\n" );
return( -1 );
}
return( buffer.st_size );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -