⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 par4chkd.c

📁 基于PC104的24位数据采集器的完整源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* FILE: par4chkd.c             Copyright (c), Symmetric Research, 2001

Par4ch device driver functions for all OS's.

For Windows NT and Linux, the device driver must first be installed
by running the provided indriver utility.

For Windows 95 and DOS, the device driver functions are made
available by linking them in with the par4ch.c library functions at
compile time.

Users then interact with the driver functions by calling the par4ch.c
library functions.

*/





/* DEBUGGING DEFINE:

This define controls the level of printf type degguing that will come
from the kernel mode driver.  -1 = no printf debugging statements.
SRDBG = (1,2,3,4,5) -> various levels of reporting.  Production
compiles are done with -1.

*/

#define SRDBG  -1





/* PAR4CH REV B,C TEST VOLTAGE DEFINES:

These defines control whether the voltage good signal is tested or
not.  Setting the _BAD define to 1 tests the voltage at the end of
the PowerDown function when the voltage should be off.  Setting the
_GOOD define to 1 tests the voltage at the end of the PowerUp
function when the voltage should be good.  Setting either define to 0
ignores the respective voltage test.

Production compiles are done with _BAD set to 0 and _GOOD set to 1.
This is done because some PC's don't provide a pull-up resistor on
the voltage good line.  This resistor is needed to pull the active
low voltage good signal up to a 1 when power on the PAR4CH board is
off.  Once the PAR4CH board has power, it can reliably pull the
signal low to indicate good voltage.

Most PAR4CH Rev B boards did not support the voltage good signal, so
they should use 0 for both defines.

*/

#define PAR4CH_TEST_VOLTAGE_BAD   0
#define PAR4CH_TEST_VOLTAGE_GOOD  1




/* PAR4CH REV B TEST OVERFLOW DEFINE:

This define controls whether the overflow signal is tested or not.
Set it to 1 to test the overflow signal and 0 to ignore it.

Production compiles are done with this define set to 1.  Most PAR4CH
Rev B boards did not support the overflow signal, so they should use 0.

*/

#define PAR4CH_TEST_OVERFLOW   0





/* LOCAL DEFINE:

This define controls whether the driver functions are visible to
other source files.  Most users should let SRLOCAL be defined as
static to avoid namespace clutter and possible function name
contention.  The only exceptions would be for specialized debugging
and diagnostic programs.

*/

#if !defined( SRLOCAL )
#define SRLOCAL static
#endif



/* OS dependent includes, defines, and typedefs.
 *
 *
 *
*/

#if defined( SROS_WINNT )
#include <ntddk.h>
#include <stdio.h>
#include "par4chlg.h"  // includes error log codes
#define ATOMIC  long 


#elif defined( SROS_WIN95 ) || defined( SROS_MSDOS )
#include <stdio.h>
#include <malloc.h>
#define WCHAR             char // unsigned short
#define ATOMIC            long 
typedef struct _irpcb {
        unsigned long  Command;
        unsigned long  Nbytes;
        void          *InBuffer;
        void          *OutBuffer;
        } IRP;
#define STATUS_SUCCESS                          (0x00000000L) // ntsubauth
#define STATUS_INVALID_PORT_ATTRIBUTES          (0xC000002EL)
#define STATUS_TOKEN_ALREADY_IN_USE             (0xC000012BL)
#define STATUS_NO_TOKEN                         (0xC000007CL)
#define STATUS_INVALID_PARAMETER                (0xC000000DL)
#define STATUS_INVALID_USER_BUFFER              (0xC00000E8L)
#define STATUS_INVALID_DEVICE_REQUEST           (0xC0000010L)
#define STATUS_DEVICE_CONFIGURATION_ERROR       (0xC0000182L)
#define STATUS_DEVICE_DATA_ERROR                (0xC000009CL)
#define STATUS_PIPE_EMPTY                       (0xC00000D9L)



#elif defined( SROS_LINUX )
#include "lnxver.h"           // Account for kernel changes
#include <linux/errno.h>      // error codes
#include <asm/ioctl.h>        // _IOC ioctrl macros
#include <asm/io.h>           // in and out
#include <asm/atomic.h>       // atomic inc and dec
#define WCHAR             char
#define ATOMIC            atomic_t
typedef struct _irpcb {
        unsigned long  Command;
        unsigned long  Nbytes;
        void          *InBuffer;
        void          *OutBuffer;
        } IRP;
#define STATUS_SUCCESS                          (0x00000000L)
#define STATUS_INVALID_PORT_ATTRIBUTES          ((long)(-EINVAL))
#define STATUS_TOKEN_ALREADY_IN_USE             ((long)(-EBUSY))
#define STATUS_NO_TOKEN                         ((long)(-ENXIO))
#define STATUS_INVALID_PARAMETER                ((long)(-EINVAL))
#define STATUS_INVALID_USER_BUFFER              ((long)(-EFAULT))
#define STATUS_INVALID_DEVICE_REQUEST           ((long)(-EINVAL))
#define STATUS_DEVICE_CONFIGURATION_ERROR       ((long)(-ENODEV))
#define STATUS_DEVICE_DATA_ERROR                ((long)(-EIO))
#define STATUS_PIPE_EMPTY                       ((long)(-EAGAIN))


#endif  // SROS_xxxxx







/* Common includes and defines:

These includes and defines are the same across all the OS's.

*/

#include "par4ch.h"    // includes PAR4CH defines shared with the user & DLL
#include "par4chkd.h"  // includes IOCTL codes and device name defines
#include "dbgprint.h"  // for debugging

#define DEFAULT_PORT_NAME       PAR4CH_0x378
#define DEFAULT_PORT_ADDRESS    0x378
#define DEFAULT_PORT_COUNT      5
#define DEFAULT_DEV_MAJOR       123

#define MAX_STR_LENGTH          256








/* DEVICE INFORMATION STRUCTURE:

This structure contains all the global data which the driver code
needs.  It is passed to most functions.

PKFN_IOWR and PKFN_IORD are typedefs for the EPP/BPP read/write
function pointers in struct DeviceInformation.

*/

struct DeviceInformation;  // forward declaration

typedef void (*PKFN_IOWR)( struct DeviceInformation *Dev, unsigned char  Value);
typedef void (*PKFN_IORD)( struct DeviceInformation *Dev, unsigned char *Value);

SRLOCAL struct DeviceInformation {
        

        // Parallel port base address and mode.
        
        int ParPortBase;
        int ParPortMode;

        
        // Parallel port register addresses.
        
        int ParPortData;  // ParPortBase + 0
        int ParPortStat;  // ParPortBase + 1
        int ParPortCtrl;  // ParPortBase + 2
        int EppPortAddr;  // ParPortBase + 3
        int EppPortData;  // ParPortBase + 4

        
        // Parallel port read/write function pointers that vary with
        // port EPP/BPP mode.
        
        PKFN_IORD ParPortAsRd;
        PKFN_IOWR ParPortAsWr;
        PKFN_IORD ParPortDsRd;
        PKFN_IOWR ParPortDsWr;


        // Parallel port current control register value.

        unsigned char ParPortCtrlValue;


        // Par4ch on board control register value.
        
        unsigned char BdCtrlValue;


        // Par4ch / ADS1210 command register value (32 bits).

        long ADS1210SaveCrValue;


        // Par4ch / ADS1210 data format (signed vs offset).

        int DataFormat;

        
        // Expected DRAM FIFO sanity bit value.

        unsigned char ExpectedFifoSanity;

        
        // Decimation data for lower sampling rates ( < 40Hz ).
        
        int  ExtraDecNavg;
        int  ExtraDecNcount;
        long ExtraDecSum[PAR4CH_CHANNELS];


        // Controls whether the Par4ch powers down on exit

        int PowerDownOnExitFlag;
        
        
        // Usage lock so only 1 process is using the driver at a time.

        int NumberOpensLock;


        // Error message buffer.
        
        WCHAR MsgBuffer[MAX_STR_LENGTH];


} Par4chDeviceInfo;


typedef struct DeviceInformation DEVINFO;





/* FUNCTION PROTOTYPES:
 *
 *
 *
 *
 */

// OS specific helper functions

SRLOCAL void OsPortIn( int port, unsigned char *value );
SRLOCAL void OsPortOut( int port, unsigned char value );
SRLOCAL unsigned long OsCopyToUser( void *UserBuff, const void *KernelBuff, unsigned long Nbytes );
SRLOCAL unsigned long OsCopyFromUser( void *KernelBuff, const void *UserBuff, unsigned long Nbytes );
SRLOCAL void OsIrpFinish( IRP *Irp, long Status, unsigned long Info );
SRLOCAL long OsSetReadParms( IRP *Irp, unsigned long *OutBufferSize, long **IOBuffer );
SRLOCAL void OsSetIoctlCommand( IRP *Irp, unsigned long *Command );
SRLOCAL long OsSetIoctlBuffers( IRP *Irp,
                                unsigned long Command,
                                int **InBuffer,
                                int **OutBuffer );
SRLOCAL void OsReturnIoctlBuffer( IRP *Irp,
                                  unsigned long Command,
                                  int *OutBuffer );

// OS specific macro helper functions
// OsAtomicSet,OsAtomicInc,OsAtomicDec,OsAtomicAdd,OsAtomicSub,OsAtomicRead
// OsModuleUseCountInc,OsModuleUseCountDec


// Helper functions that interface with the Par4ch and its components

SRLOCAL void Par4ch_ParPortInit( DEVINFO *Dev );

SRLOCAL void Par4ch_ParPortDataRd( DEVINFO *Dev, unsigned char *Value );
SRLOCAL void Par4ch_ParPortDataWr( DEVINFO *Dev, unsigned char Value );
SRLOCAL void Par4ch_ParPortStatRd( DEVINFO *Dev, unsigned char *Value );
SRLOCAL void Par4ch_ParPortCtrlWr( DEVINFO *Dev, unsigned char Value );
SRLOCAL void Par4ch_ParPortCtrlRw( DEVINFO *Dev, unsigned char Value);
SRLOCAL void Par4ch_ParPortCtrlIrqen( DEVINFO *Dev, unsigned char Value);
SRLOCAL void Par4ch_ParPortCtrlPdir( DEVINFO *Dev, unsigned char Value);

SRLOCAL void Par4ch_Wait( DEVINFO *Dev, unsigned int Milliseconds );
SRLOCAL int  Par4ch_VoltageGood( DEVINFO *Dev );
SRLOCAL int  Par4ch_PowerDown( DEVINFO *Dev );
SRLOCAL int  Par4ch_PowerUp( DEVINFO *Dev );

SRLOCAL void Par4ch_EppAsRd( DEVINFO *Dev, unsigned char *Value );
SRLOCAL void Par4ch_EppAsWr( DEVINFO *Dev, unsigned char  Value );
SRLOCAL void Par4ch_EppDsRd( DEVINFO *Dev, unsigned char *Value );
SRLOCAL void Par4ch_EppDsWr( DEVINFO *Dev, unsigned char  Value );

SRLOCAL void Par4ch_BppAsRd( DEVINFO *Dev, unsigned char *Value );
SRLOCAL void Par4ch_BppAsWr( DEVINFO *Dev, unsigned char  Value );
SRLOCAL void Par4ch_BppDsRd( DEVINFO *Dev, unsigned char *Value );
SRLOCAL void Par4ch_BppDsWr( DEVINFO *Dev, unsigned char  Value );

SRLOCAL void Par4ch_BdCtrlWr( DEVINFO *Dev, unsigned char Value );
SRLOCAL void Par4ch_BdCtrlInit( DEVINFO *Dev );
SRLOCAL void Par4ch_BdCtrlMode( DEVINFO *Dev, unsigned char Value );
SRLOCAL void Par4ch_BdCtrlDsync( DEVINFO *Dev, unsigned char Value );
SRLOCAL void Par4ch_BdCtrlFifoReset( DEVINFO *Dev, unsigned char Value );
SRLOCAL void Par4ch_BdCtrlUserLed( DEVINFO *Dev, int State );

SRLOCAL void Par4ch_ADS1210_WriteByte( DEVINFO *Dev, unsigned char  Value );
SRLOCAL void Par4ch_ADS1210_ReadByte( DEVINFO *Dev, unsigned char *Value );

SRLOCAL void Par4ch_ADS1210_ReadReg24( DEVINFO *Dev, int reg, long *Value );
SRLOCAL void Par4ch_ADS1210_ReadReg32( DEVINFO *Dev, int reg, long *Value );
SRLOCAL void Par4ch_ADS1210_WriteReg24( DEVINFO *Dev, int reg, unsigned long Value );
SRLOCAL void Par4ch_ADS1210_WriteReg32( DEVINFO *Dev, int reg, unsigned long Value );

SRLOCAL void Par4ch_DramFifoReset( DEVINFO *Dev );
SRLOCAL void Par4ch_DramFifoRd( DEVINFO *Dev, unsigned char *Value );
SRLOCAL void Par4ch_DramFifoWr( DEVINFO *Dev, unsigned char Value );
SRLOCAL int  Par4ch_DramFifoReady( DEVINFO *Dev );
SRLOCAL int  Par4ch_DramFifoFull( DEVINFO *Dev );
SRLOCAL int  Par4ch_DramFifoReadDemux( DEVINFO *Dev, long *Values );
SRLOCAL int  Par4ch_DramFifoWriteMux( DEVINFO *Dev, long *Values );

SRLOCAL void Par4ch_UserIoRd( DEVINFO *Dev, int *Value );
SRLOCAL void Par4ch_UserIoWr( DEVINFO *Dev, int Value );

SRLOCAL void Par4ch_InterruptEnable( DEVINFO *Dev );
SRLOCAL void Par4ch_InterruptDisable( DEVINFO *Dev );

SRLOCAL void Par4ch_Init( DEVINFO *Dev, int *IOBuffer );
SRLOCAL void Par4ch_Start( DEVINFO *Dev );
SRLOCAL void Par4ch_Stop( DEVINFO *Dev );


// Helper functions

SRLOCAL void Par4ch_FillDevInfo( DEVINFO *Dev, int ParPortBase );


// Driver dispatch functions called "directly" from the OS

SRLOCAL long Par4ch_DrvOpen( DEVINFO *Dev, IRP *Irp );
SRLOCAL long Par4ch_DrvClose( DEVINFO *Dev, IRP *Irp );
SRLOCAL long Par4ch_DrvRead( DEVINFO *Dev, IRP *Irp );
SRLOCAL long Par4ch_DrvIoctl( DEVINFO *Dev, IRP *Irp );

SRLOCAL void Par4ch_DrvUnload( DEVINFO *Dev );



// OS dependent initialization and "dispatch" functions:

#if defined( SROS_WINNT )

// WinNT Helper Functions

SRLOCAL char *Winnt_AddressToName( int PortAddress );

SRLOCAL NTSTATUS Winnt_ErrorLog( void *IoObject,
                                 IRP *Irp,
                                 NTSTATUS CurrStatus,
                                 unsigned long ErrCode,
                                 const WCHAR *Msg );

SRLOCAL NTSTATUS Winnt_GetParameters( UNICODE_STRING *RegistryPath,
                                      unsigned long *Portbase );

SRLOCAL NTSTATUS Winnt_PortFree( DRIVER_OBJECT *DriverObject );

SRLOCAL NTSTATUS Winnt_PortReserve( DRIVER_OBJECT *DriverObject,
                                    unsigned long Portbase,
                                    PHYSICAL_ADDRESS *MappedAddress );

SRLOCAL void Winnt_ResourceFree( DRIVER_OBJECT *DriverObject,
                                 UNICODE_STRING *NtDeviceName,
                                 DEVICE_OBJECT *DeviceObject,
                                 UNICODE_STRING *Win32DeviceName,
                                 int SymLink );


// WinNT Functions called from the OS

NTSTATUS Winnt_DrvOpen(  DEVICE_OBJECT *DeviceObject, IRP *Irp );
NTSTATUS Winnt_DrvClose( DEVICE_OBJECT *DeviceObject, IRP *Irp );
NTSTATUS Winnt_DrvRead(  DEVICE_OBJECT *DeviceObject, IRP *Irp );
NTSTATUS Winnt_DrvIoctl( DEVICE_OBJECT *DeviceObject, IRP *Irp );

void Winnt_DrvUnload( DRIVER_OBJECT *DriverObject );

NTSTATUS DriverEntry( DRIVER_OBJECT *DriverObject,
                      UNICODE_STRING *RegistryPath );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -