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

📄 driver.cpp

📁 美国国家半导体公司的扫描仪芯片LM9833的驱动程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
M+
    Copyright (c) 1998,1999 by National Semiconductor
        All Rights Reserved.

M- 
*****************************************************************************/
// File: Driver.cpp 
// 

#include "stdafx.h"
#include "driver.h"

#include <sti.h>                     // Still Image services
#include "usbscan.h"				 // STI USB Interface
#include <Winioctl.h>                // IOCTL codes and Macros
#include "..\NSCStiu\NscUsbIO.h"

/*****************************************************************************

  Global still image information

*****************************************************************************/
PSTI					g_pSti = NULL;        // handle to STI subsystem
PVOID                   g_pStiInfo = NULL;    // STI device info buffer
PSTI_DEVICE_INFORMATION g_pStiInfoPtr = NULL; // pointer to device in pStiBuffer
int                     g_nStiNumber = 0;     // 0 based index into g_pStiInfo
DWORD                   g_dwStiTotal = 0;     // total number of STI devices found
PSTIDEVICE				g_pStiDevice = NULL;  // STI device being used
HANDLE					g_hEvent	= INVALID_HANDLE_VALUE; 
												// Interrupt event handle
/*****************************************************************************

  Module specific Consts and # Defines 

*****************************************************************************/
const LPWSTR MERLIN_DEVICE1			= L"LM9831 USB Scanner";
const LPWSTR MERLIN_DEVICE2			= L"LM9832 USB Scanner";
const LPWSTR MERLIN_DEVICE3			= L"TravelScan FS531";
const LPWSTR MERLIN_MANUFACTURER	= L"Syscan Inc";

// The first byte for the bulk register reads is the mode 
// byte and this is bit mapped 
// Bit 0 , 1 - Read, 0 - Write
// Bit 1 , 1 - Inc, 0 - No Inc
const BYTE MODE_INC_READ	= 0x03;
const BYTE MODE_NOINC_READ	= 0x01;
const BYTE MODE_INC_WRITE	= 0x02;
const BYTE MODE_NOINC_WRITE = 0x00;

#define COMMAND_BYTE_COUNT	4
#define LOCK_TIMEOUT		2000

/*****************************************************************************

 Private STI api helper method prototypes

*****************************************************************************/
HRESULT StiImageRelease();
HRESULT StiDeviceRelease();
HRESULT StiWriteErrLog(DWORD,LPCWSTR);

/*****************************************************************************

 CDriver Implementation

*****************************************************************************/
//
// Construct of class CDriver
//
CDriver::CDriver()
{
	g_hEvent = INVALID_HANDLE_VALUE;
}

//
// Function CDriver destructor
//
CDriver::~CDriver()
{
	CloseDriver();
}


//
// Function to initialize device driver
//
BOOL CDriver::InitDriver(void)
{
    HRESULT hres = STI_OK;
	
	// Close the driver if it has been already opened
	CloseDriver();

	//
	// The StiCreateInstance interface locates the primary still image interface.
	// Use this call to optain the pointer to the IStillImage interface.
	//
	hres = StiCreateInstance(
		GetModuleHandle(NULL),  // instance handle of this application
		STI_VERSION,            // STI version
		&g_pSti,                  // pointer to IStillImage interface
		NULL                    // pointer to controlling unknown of OLE aggregation
		);
	
	if (FAILED(hres))
		return false;

	// Get the device list and try to locate our device
    DWORD   dwCounter;

    // Enumerate devices
	g_dwStiTotal = 0;
	g_pStiInfo = NULL;

	//
	// The GetDeviceList interface is used to get a list of the installed still
	// image devices. Use this call to obtain a STI_DEVICE_INFORMATION array
	// filled with info on all currently installed STI devices. 
	// * NOTE: the STI subsystem allocates memory for the STI device information
	// buffer, but the caller needs to free this memory with LocalFree().
	//
    hres = g_pSti->GetDeviceList(
			NULL,           // Type (reserved, use NULL)
			NULL,           // Flags (reserved, use NULL)
			&g_dwStiTotal,    // address of variable to return number of devices found
			&g_pStiInfo       // STI device info buffer
			);

    if (! SUCCEEDED(hres))
		return false;

    //
    // Compare the info on each device found with the info for our
	// device
    //
	for (dwCounter = 0,g_pStiInfoPtr = (PSTI_DEVICE_INFORMATION) g_pStiInfo;
        dwCounter < g_dwStiTotal;
        dwCounter++, g_pStiInfoPtr++) 
	{
		// If the manufacturer Id matches and the device is either the Merlin 
        // I Scanner (LM9831) or the Merlin II scanner (LM9832) then we have 
        // found a match for our device
        if (!wcsicmp(g_pStiInfoPtr->pszVendorDescription, MERLIN_MANUFACTURER) &&
		    ( !wcsicmp(g_pStiInfoPtr->pszDeviceDescription, MERLIN_DEVICE1 )|| 
              !wcsicmp(g_pStiInfoPtr->pszDeviceDescription, MERLIN_DEVICE2 )||
              !wcsicmp(g_pStiInfoPtr->pszDeviceDescription, MERLIN_DEVICE3) 			  
            ) )
		{
			//
			// Open the device - it is now pointed to by g_pStiInfoPtr
			// The CreateDevice interface creates an IStiDevice object.
			// The IStiDevice object provides access to the IStiDevice interface
			// and device specific Imaging functionality.
			//
			hres = g_pSti->CreateDevice(
				g_pStiInfoPtr->szDeviceInternalName,  // internal device name
				STI_DEVICE_CREATE_STATUS,  // device creation mode
				&g_pStiDevice,            // pointer where IStiDevice object is to be stored
				NULL );                 // pointer to controlling unknown of OLE aggregation
			if (SUCCEEDED(hres)) return true;
		}
    }

    return false;
}
						
// Close Driver
BOOL CDriver::CloseDriver()
{
	HRESULT hres = STI_OK;

	// We dont care if this fails we still 
	// have to close the STI Image Subsystem
	// Storing the result just helps debugging
	hres = StiDeviceRelease();
	
	hres = StiImageRelease();

	return SUCCEEDED(hres);
}

//Reg in
BOOL	CDriver::RegIn(UCHAR Addr, UCHAR *pValue, UINT Len)
{
	if (!g_pStiDevice)
		return FALSE;

	HRESULT hres = STI_OK;
	
	IO_BLOCK	stIoBlock;

	stIoBlock.uOffset = Addr;
	stIoBlock.uLength = Len;
	stIoBlock.pbyData = pValue;
	stIoBlock.uIndex  = 0;

	DWORD cbBytes = sizeof(UCHAR);

	hres = g_pStiDevice->LockDevice(LOCK_TIMEOUT);

	if (SUCCEEDED(hres)) 
	{
		hres = 	g_pStiDevice->RawReadCommand(&stIoBlock, &cbBytes, NULL);
	
		g_pStiDevice->UnLockDevice();
	
	}


	return SUCCEEDED(hres);
}

//Reg out
BOOL	CDriver::RegOut(UCHAR Addr,UCHAR* pValue, UINT Len)
{
	if (!g_pStiDevice)
		return FALSE;

	HRESULT hres = STI_OK;
	
	IO_BLOCK	stIoBlock;

	stIoBlock.uOffset = Addr;
	stIoBlock.uLength = Len;
	stIoBlock.pbyData = pValue;
	stIoBlock.uIndex  = 0;

	DWORD cbBytes = sizeof(UCHAR);

	hres = g_pStiDevice->LockDevice(LOCK_TIMEOUT);
	
	if (SUCCEEDED(hres)) 
	{
		hres = 	g_pStiDevice->RawWriteCommand(&stIoBlock, cbBytes, NULL);

		g_pStiDevice->UnLockDevice();
	}


	return SUCCEEDED(hres);
}

//Bulk in
BOOL	CDriver::BulkIn(UCHAR Addr,UCHAR *pBuffer,UINT Len, bool bIncrement)
{
	if (!g_pStiDevice)
		return FALSE;

	HRESULT hres = STI_OK;

	// To read registers via the bulk in endpoint send the 
	// command byte stream on the Bulk out endpoint and then
	// send in the read request on the bulk in endpoint

	hres = g_pStiDevice->LockDevice(LOCK_TIMEOUT);
	
	//must handle >= 64K size 
	const UINT Max_Bulk_In_Size=0xffff; 
	BYTE pCommandBytes[COMMAND_BYTE_COUNT];
	DWORD cbBytes;
	for (UINT i = 0; i < Len; i+=Max_Bulk_In_Size)
	{
		cbBytes = min(Max_Bulk_In_Size,Len-i);

		if (SUCCEEDED(hres)) 
		{
			pCommandBytes[0] = bIncrement ? MODE_INC_READ : MODE_NOINC_READ;
			pCommandBytes[1] = Addr+(bIncrement ? i : 0);
			pCommandBytes[2] = (BYTE) (cbBytes >> 8); 
			pCommandBytes[3] = (BYTE) (cbBytes & 0xff);
			hres = 	g_pStiDevice->RawWriteData(&pCommandBytes, 
												COMMAND_BYTE_COUNT, 
												NULL);
			if (SUCCEEDED(hres) )
			{
//				cbBytes = 0; //TEST!!!!!!
				hres = 	g_pStiDevice->RawReadData(&pBuffer[i], &cbBytes, NULL);
			}
		}
	}
	g_pStiDevice->UnLockDevice();

	if (!SUCCEEDED(hres)) Reset();

	return SUCCEEDED(hres);
}

//Bulk out
BOOL	CDriver::BulkOut(UCHAR Addr,UCHAR *pBuffer,UINT Len, bool bIncrement)
{
	if (!g_pStiDevice)
		return FALSE;

	HRESULT hres = STI_OK;

	// To read registers via the bulk in endpoint send the 
	// command byte stream on the Bulk out endpoint and then
	// send in the write request on the bulk out endpoint
	
	hres = g_pStiDevice->LockDevice(LOCK_TIMEOUT);

	const UINT Max_Bulk_Out_Size=60;
	BYTE pCommandBytes[COMMAND_BYTE_COUNT+Max_Bulk_Out_Size];
	DWORD cbBytes;
	//must handle >= 60 size 
	for (UINT i = 0; i < Len; i+=Max_Bulk_Out_Size)
	{
		cbBytes = min(Max_Bulk_Out_Size,Len-i);

		pCommandBytes[0] = bIncrement ? MODE_INC_WRITE : MODE_NOINC_WRITE;
		pCommandBytes[1] = Addr+(bIncrement ? i : 0);
		pCommandBytes[2] = (BYTE) (cbBytes >> 8); 
		pCommandBytes[3] = (BYTE) (cbBytes & 0xff);
		for (UINT j = 0; j < cbBytes; j++)
			pCommandBytes[COMMAND_BYTE_COUNT+j] = pBuffer[i+j];

		if (SUCCEEDED(hres)) 
		{
			hres = 	g_pStiDevice->RawWriteData( &pCommandBytes, 

⌨️ 快捷键说明

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