windows-nt/Source/XPSP1/NT/printscan/wia/test/devctrl/pmxe3.cpp
2020-09-26 16:20:57 +08:00

1210 lines
29 KiB
C++

#include "stdafx.h"
#include "pmxe3.h"
#include "datadump.h"
CPMXE3::CPMXE3(PDEVCTRL pDeviceControl)
{
m_pDeviceControl = pDeviceControl;
m_scanmode = scHalftone;
InitializeRegisters();
}
CPMXE3::~CPMXE3()
{
}
VOID CPMXE3::InitializeRegisters()
{
Register0 =0x00;
//Register1 =0x5a;
//Register2 =0x00;
Register3 =0x0f;
Register4 =0x32;
Register5 =0x14;
Register6 =0x95;
Register7 =0x07;
Register8 =0xd0;
Register9 =0x0a;
Register10=0x0f;
Register11=0xa0;
Register12=0x40;
Register13=0x80;
//Register14=0x00;
//Register15=0x00;
//Register16=0x00;
//Register17=0x00;
//Register18=0x00;
//Register19=0x00;
Register20=0x00;
Register21=0x00;
Register22=0x13;
Register23=0xec;
//Register24=0xff;
Register25=0x14;
Register26=0x18;
Register27=0x11;
Register28=0x2c;
Register29=0x2c;
//Register30=0x00;
Register31=0x00;
//Register32=0x00;
//Register33=0x00;
//Register34=0x00;
//Register35=0x00;
#ifdef DEBUG
Trace(TEXT("Register Dump - At InitRegisters() Call"));
DebugDumpRegisters();
#endif
}
VOID CPMXE3::DebugDumpRegisters()
{
//
// dump Init registers initial values
//
WORD CarriageStep = MAKEWORD(Register8,Register7); // 2000
WORD ScanAreaStart = MAKEWORD(Register21,Register20); // 0
WORD ScanAreaWidth = MAKEWORD(Register23,Register22); // 5100
WORD XResolution = MAKEWORD(Register28,((E3_REG27*)&Register27)->XRes); // 300 dpi
WORD YResolution = MAKEWORD(Register29,((E3_REG27*)&Register27)->YRes); // 300 dpi
WORD TriggerPeriod = MAKEWORD(Register11,Register10); // 4000
Trace(TEXT("- WORD constructed Register values -"));
Trace(TEXT("Carriage Step: %d"),CarriageStep);
Trace(TEXT("ScanAreaStart: %d"),ScanAreaStart);
Trace(TEXT("ScanAreaWidth: %d"),ScanAreaWidth);
Trace(TEXT("XResolution: %d"),XResolution);
Trace(TEXT("YResolution: %d"),YResolution);
Trace(TEXT("TriggerPeriod %d"),TriggerPeriod);
Trace(TEXT("------------------------------------"));
E3_REG3* pRegister3 = (E3_REG3*)&Register3;
Trace(TEXT("- Register3 -"));
Trace(TEXT("EppUsb = %d"),pRegister3->EppUsb);
Trace(TEXT("FifoReset = %d"),pRegister3->FifoReset);
Trace(TEXT("ScanSpeed = %d"),pRegister3->ScanSpeed);
Trace(TEXT("SelfTest = %d"),pRegister3->SelfTest);
Trace(TEXT("SystemReset = %d"),pRegister3->SystemReset);
Trace(TEXT("WatchDog = %d"),pRegister3->WatchDog);
Trace(TEXT("----------------"));
E3_REG4* pRegister4 = (E3_REG4*)&Register4;
Trace(TEXT("- Register4 -"));
Trace(TEXT("AsicTest = %d"),pRegister4->AsicTest);
Trace(TEXT("Refresh = %d"),pRegister4->Refresh);
Trace(TEXT("RefreshForever = %d"),pRegister4->RefreshForever);
Trace(TEXT("ScanMode = %d"),pRegister4->ScanMode);
Trace(TEXT("WaitDelay = %d"),pRegister4->WaitDelay);
Trace(TEXT("YTable = %d"),pRegister4->YTable);
Trace(TEXT("----------------"));
E3_REG5* pRegister5 = (E3_REG5*)&Register5;
Trace(TEXT("- Register5 -"));
Trace(TEXT("Adc1210 = %d"),pRegister5->Adc1210);
Trace(TEXT("Afe = %d"),pRegister5->Afe);
Trace(TEXT("Sensor = %d"),pRegister5->Sensor);
Trace(TEXT("Sensor_Res = %d"),pRegister5->Sensor_Res);
Trace(TEXT("----------------"));
E3_REG6* pRegister6 = (E3_REG6*)&Register6;
Trace(TEXT("- Register6 -"));
Trace(TEXT("FullHalf = %d"),pRegister6->FullHalf);
Trace(TEXT("LineOffset = %d"),pRegister6->LineOffset);
Trace(TEXT("MotorPower = %d"),pRegister6->MotorPower);
Trace(TEXT("Operation = %d"),pRegister6->Operation);
Trace(TEXT("----------------"));
E3_REG12* pRegister12 = (E3_REG12*)&Register12;
Trace(TEXT("- Register12 -"));
Trace(TEXT("FifoEmpty = %d"),pRegister12->FifoEmpty);
Trace(TEXT("FinishFlag = %d"),pRegister12->FinishFlag);
Trace(TEXT("HomeSensor = %d"),pRegister12->HomeSensor);
Trace(TEXT("HwSelfTest = %d"),pRegister12->HwSelfTest);
Trace(TEXT("Lamp = %d"),pRegister12->Lamp);
Trace(TEXT("MotorMove = %d"),pRegister12->MotorMove);
Trace(TEXT("MotorStop = %d"),pRegister12->MotorStop);
Trace(TEXT("ScanStatus = %d"),pRegister12->ScanStatus);
Trace(TEXT("----------------"));
E3_REG13* pRegister13 = (E3_REG13*)&Register13;
Trace(TEXT("- Register13 -"));
Trace(TEXT("Cs = %d"),pRegister13->Cs);
Trace(TEXT("Reserved = %d"),pRegister13->Reserved);
Trace(TEXT("Sclk = %d"),pRegister13->Sclk);
Trace(TEXT("Sdi = %d"),pRegister13->Sdi);
Trace(TEXT("Sdo = %d"),pRegister13->Sdo);
Trace(TEXT("WmVsamp = %d"),pRegister13->WmVsamp);
Trace(TEXT("----------------"));
E3_REG26* pRegister26 = (E3_REG26*)&Register26;
Trace(TEXT("- Register26 -"));
Trace(TEXT("Start = %d"),pRegister26->Start);
Trace(TEXT("Stop = %d"),pRegister26->Stop);
Trace(TEXT("----------------"));
E3_REG31* pRegister31 = (E3_REG31*)&Register31;
Trace(TEXT("- Register31 -"));
Trace(TEXT("Key0 = %d"),pRegister31->Key0);
Trace(TEXT("Key1 = %d"),pRegister31->Key1);
Trace(TEXT("Key2 = %d"),pRegister31->Key2);
Trace(TEXT("Key3 = %d"),pRegister31->Key3);
Trace(TEXT("Key4 = %d"),pRegister31->Key4);
Trace(TEXT("Key5 = %d"),pRegister31->Key5);
Trace(TEXT("Key6 = %d"),pRegister31->Key6);
Trace(TEXT("Key7 = %d"),pRegister31->Key7);
Trace(TEXT("----------------"));
Trace(TEXT("--- END REGISTER DUMP ---"));
}
BOOL CPMXE3::WriteRegister(INT RegisterNumber, BYTE Value)
{
DWORD cbRet = 0;
BOOL bSuccess = FALSE;
BYTE pData[2];
pData[0] = BYTE(RegisterNumber);
pData[1] = Value;
IO_BLOCK IoBlock;
IoBlock.uOffset = (BYTE)IOCTL_EPP_WRITE;
IoBlock.uLength = 2;
IoBlock.pbyData = pData;
bSuccess = DeviceIoControl(m_pDeviceControl->DeviceIOHandles[m_pDeviceControl->BulkInPipeIndex],
(DWORD) IOCTL_WRITE_REGISTERS,
&IoBlock,
sizeof(IO_BLOCK),
NULL,
0,
&cbRet,
NULL);
return bSuccess;
}
BOOL CPMXE3::WriteRegisterEx(INT RegisterNumber, BYTE Value)
{
BYTE pbuffer[64];
memset(pbuffer,0,sizeof(pbuffer));
pbuffer[0] = CMD_WRITE;
pbuffer[1] = (BYTE)RegisterNumber;
pbuffer[2] = 0; // length: low byte
pbuffer[3] = 1; // length: high byte
pbuffer[4] = Value;
return RawWrite(m_pDeviceControl->BulkInPipeIndex,
pbuffer,
64,
0);
}
BOOL CPMXE3::ReadRegister(INT RegisterNumber, BYTE *pValue)
{
DWORD cbRet = 0;
BOOL bSuccess = FALSE;
IO_BLOCK IoBlock;
IoBlock.uOffset = MAKEWORD(IOCTL_EPP_READ, (BYTE)RegisterNumber);
IoBlock.uLength = 1;
IoBlock.pbyData = pValue;
bSuccess = DeviceIoControl(m_pDeviceControl->DeviceIOHandles[m_pDeviceControl->BulkOutPipeIndex],
(DWORD) IOCTL_READ_REGISTERS,
(PVOID)&IoBlock,
(DWORD)sizeof(IO_BLOCK),
(PVOID)pValue,
(DWORD)sizeof(BYTE),
&cbRet,
NULL);
return bSuccess;
}
BOOL CPMXE3::ReadRegisterEx(INT RegisterNumber, BYTE *pValue)
{
BYTE pbuffer[64];
memset(pbuffer,0,sizeof(pbuffer));
pbuffer[0] = CMD_READ;
pbuffer[1] = (BYTE)RegisterNumber;
pbuffer[2] = 0; // length: low byte
pbuffer[3] = 1; // length: high byte
LONG BytesRead = 0;
*pValue = 0;
if(!RawWrite(m_pDeviceControl->BulkInPipeIndex, pbuffer, 64, 0)){
return FALSE;
}
if(!RawRead(m_pDeviceControl->BulkOutPipeIndex, pbuffer, 64, &BytesRead,0)){
return FALSE;
}
*pValue = pbuffer[0];
return TRUE;
}
BOOL CPMXE3::SetXRes(LONG xRes)
{
m_xres = xRes;
return TRUE;
}
BOOL CPMXE3::SetYRes(LONG yRes)
{
m_yres = yRes;
return TRUE;
}
BOOL CPMXE3::SetXPos(LONG xPos)
{
m_xpos = xPos;
return TRUE;
}
BOOL CPMXE3::SetYPos(LONG yPos)
{
m_ypos = yPos;
return TRUE;
}
BOOL CPMXE3::SetXExt(LONG xExt)
{
m_xext = xExt;
return TRUE;
}
BOOL CPMXE3::SetYExt(LONG yExt)
{
m_yext = yExt;
return TRUE;
}
BOOL CPMXE3::SetDataType(LONG DataType)
{
m_datatype = DataType;
switch (m_datatype) {
case 0: // WIA_DATA_THRESHOLD
m_scanmode = scHalftone;
break;
case 1: // WIA_DATA_GRAYSCALE
m_scanmode = scGrayScale;
break;
case 2: // WIA_DATA_COLOR
m_scanmode = scFullColor;
break;
default:
return FALSE;
break;
}
return TRUE;
}
///////////////////////
// //
// DEVICE OPERATIONS //
// //
///////////////////////
BOOL CPMXE3::Lamp(BOOL bON)
{
if(!ReadRegister(12,&Register12))
return FALSE;
if(bON) // lamp ON
((E3_REG12*)&Register12)->Lamp = 1;
else // lamp OFF
((E3_REG12*)&Register12)->Lamp = 0;
if(!WriteRegister(12,Register12))
return FALSE;
return TRUE;
}
BOOL CPMXE3::IsLampON()
{
if(!ReadRegister(12,&Register12))
return FALSE;
if (((E3_REG12*)&Register12)->Lamp == 1)
return TRUE;
return FALSE;
}
BOOL CPMXE3::Motor(BOOL bON)
{
if(!ReadRegister(6,&Register6))
return FALSE;
if(bON){ // Turn Motor ON
((E3_REG6*)&Register6)->MotorPower = 1;
} else { // Turn Motor OFF
((E3_REG6*)&Register6)->MotorPower = 0;
}
if(!WriteRegister(6,Register6))
return FALSE;
return TRUE;
}
BOOL CPMXE3::HomeCarriage()
{
StopScan(); // must issue a STOP before homing carriage...or the device makes
// a rather nasty grinding noise...("That can't be good.." -Cooper Partin, May 19,2000)
INT TriggerPeriod = 0;
INT ScanSpeed = 7;
INT OverCLK = 2; // perfect for E3 series models
INT ExposureTimeMin = 2000; // 2 seconds exposure time
INT ExposureTime = 12000; // possible choices, (13800,5610,11400,12000)
//
// calculate TriggerPeriod
//
if((ExposureTime / ( ScanSpeed + 1 ) ) * OverCLK < ExposureTimeMin * OverCLK)
TriggerPeriod = (INT)(ExposureTimeMin * OverCLK);
else
TriggerPeriod = (INT)((ExposureTime / ( ScanSpeed + 1 ) ) * OverCLK);
Register25 = 0x14;
if(!WriteRegister(25,Register25))
return FALSE;
if(!SetMotorSpeed(TriggerPeriod,ScanSpeed))
return FALSE;
if(!ReadRegister(6,&Register6))
return FALSE;
if(!StopMode())
return FALSE;
((E3_REG6*)&Register6)->MotorPower = 1; // motor ON
((E3_REG6*)&Register6)->Operation = 5; // auto home
if(!WriteRegister(6,Register6))
return FALSE;
//
// Prevent any operations until scanner is in HOME position...
// If any operations are done... could result in nasty noises
// and system hangs... :) (just like forcing a car into reverse, while
// driving down the freeway...)
//
while(!IsCarriageHOME()) {
Sleep(100);
}
return TRUE;
}
BOOL CPMXE3::StopMode()
{
((E3_REG6*)&Register6)->Operation = 0;
return WriteRegister(6,Register6);
}
BOOL CPMXE3::WriteStopImageRegister()
{
BYTE pbuffer[64];
memset(pbuffer,0,sizeof(pbuffer));
pbuffer[0] = CMD_STOPIMAGE;
return RawWrite(m_pDeviceControl->BulkInPipeIndex,
pbuffer,
64,
0);
}
BOOL CPMXE3::StopScan()
{
if(!WriteStopImageRegister())
return FALSE;
if(!ReadRegister(6,&Register6))
return FALSE;
((E3_REG6*)&Register6)->MotorPower = 0;
((E3_REG6*)&Register6)->Operation = 0;
if(!WriteRegister(6,Register6))
return FALSE;
((E3_REG13*)&Register13)->Sdo = 0;
((E3_REG13*)&Register13)->Sclk = 0;
if(!WriteRegister(13,Register13))
return FALSE;
Register25 = 0x14;
if(!WriteRegister(25,Register25))
return FALSE;
return TRUE;
}
BOOL CPMXE3::SetMotorSpeed(INT TriggerPeriod, INT ScanSpeed)
{
//
// set trigger period
//
Register10 = HIBYTE(TriggerPeriod/2);
Register11 = LOBYTE(TriggerPeriod/2);
if(!WriteRegister(10,Register10))
return FALSE;
if(!WriteRegister(11,Register11))
return FALSE;
//
// set scan speed
//
// Register3 = 0;
if(!ReadRegister(3,&Register3))
return FALSE;
((E3_REG3*)&Register3)->ScanSpeed = ScanSpeed;
if(!WriteRegister(3,Register3))
return FALSE;
//
// initialize motor
//
// Register6 = 0;
((E3_REG6*)&Register6)->MotorPower = 1;
((E3_REG6*)&Register6)->FullHalf = 1;
((E3_REG6*)&Register6)->Operation = 0;
if(!WriteRegister(6,Register6))
return FALSE;
return TRUE;
}
BOOL CPMXE3::MoveCarriage(BOOL bForward, INT Steps)
{
INT TriggerPeriod = 0;
INT ScanSpeed = 7; // perfect for E3 series models
INT OverCLK = 2; // perfect for E3 series models
INT ExposureTimeMin = 2000; // 2 seconds exposure time
INT ExposureTime = 12000; // possible choices, (13800,5610,11400,12000)
//
// calculate TriggerPeriod
//
if((ExposureTime / ( ScanSpeed + 1 ) ) * OverCLK < ExposureTimeMin * OverCLK)
TriggerPeriod = (INT)(ExposureTimeMin * OverCLK);
else
TriggerPeriod = (INT)((ExposureTime / ( ScanSpeed + 1 ) ) * OverCLK);
if(!SetMotorSpeed(TriggerPeriod,ScanSpeed))
return FALSE;
Register7 = HIBYTE(Steps*2); // high byte (move step)
Register8 = LOBYTE(Steps*2); // low byte (move step)
if(!WriteRegister(7,Register7))
return FALSE;
if(!WriteRegister(8,Register8))
return FALSE;
if(!StopMode())
return FALSE;
if(!ReadRegister(6,&Register6))
return FALSE;
((E3_REG6*)&Register6)->MotorPower = 1;
if(bForward) // move forward
((E3_REG6*)&Register6)->Operation = 2;
else // move backward
((E3_REG6*)&Register6)->Operation = 3;
if(!WriteRegister(6,Register6))
return FALSE;
return TRUE;
}
BOOL CPMXE3::IsCarriageHOME()
{
ReadRegister(12,&Register12);
if((Register12&CARRIAGE_HOME) != CARRIAGE_HOME)
return FALSE;
return TRUE;
}
BOOL CPMXE3::IsMotorBusy()
{
ReadRegister(12,&Register12);
if((Register12&MOTOR_BUSY) != MOTOR_BUSY)
return TRUE;
return FALSE;
}
INT CPMXE3::GetScanSpeed()
{
//
// return a preferred scan speed, with respect to
// the current y resolution.
//
if (m_yres>300)
return 0;
else if(m_yres>200)
return 1;
else if(m_yres>150)
return 2;
else if(m_yres>100)
return 3;
else if(m_yres>75)
return 5;
else if(m_yres>0)
return 7;
return 0;
}
BOOL CPMXE3::SetXandYResolution()
{
//
// X and Y resolution have to be set at the same time..
//
if(!ReadRegister(27,&Register27)){
return FALSE;
}
if(!ReadRegister(28,&Register28)){
return FALSE;
}
if(!ReadRegister(29,&Register29)){
return FALSE;
}
((E3_REG27*)&Register27)->XRes = HIBYTE(m_xres);
((E3_REG28*)&Register28)->XRes = LOBYTE(m_xres);
((E3_REG27*)&Register27)->YRes = HIBYTE(m_yres);
((E3_REG29*)&Register29)->YRes = LOBYTE(m_yres);
if(!WriteRegister(27,Register27)){
return FALSE;
}
if(!WriteRegister(28,Register28)){
return FALSE;
}
if(!WriteRegister(29,Register29)){
return FALSE;
}
return TRUE;
}
BOOL CPMXE3::SetScanWindow()
{
//
// set all three (xpos,ypos,xext,and current yext)
// at this point..
//
if(!ReadRegister(7,&Register7))
return FALSE;
if(!ReadRegister(8,&Register8))
return FALSE;
if(!ReadRegister(20,&Register20))
return FALSE;
if(!ReadRegister(21,&Register21))
return FALSE;
if(!ReadRegister(22,&Register22))
return FALSE;
if(!ReadRegister(23,&Register23))
return FALSE;
if(!ReadRegister(26,&Register26))
return FALSE;
if(!ReadRegister(4,&Register4))
return FALSE;
LONG AreaStart = m_xpos;
LONG AreaStartOffset = 146; //180;
AreaStart = (AreaStart * (600/*Hardware DPI*// m_xres));
AreaStart += AreaStartOffset;
((E3_REG20*)&Register20)->AreaStart = HIBYTE(AreaStart);
((E3_REG21*)&Register21)->AreaStart = LOBYTE(AreaStart);
if(!WriteRegister(20,Register20))
return FALSE;
if(!WriteRegister(21,Register21))
return FALSE;
((E3_REG22*)&Register22)->AreaWidth = HIBYTE(m_xext);
((E3_REG23*)&Register23)->AreaWidth = LOBYTE(m_xext);
if(!WriteRegister(22,Register22))
return FALSE;
if(!WriteRegister(23,Register23))
return FALSE;
if(!WriteRegister(27,Register27))
return FALSE;
if(!WriteRegister(28,Register28))
return FALSE;
if(!WriteRegister(29,Register29))
return FALSE;
LONG Length = 0;
LONG CutLine = 2;
LONG LineOffset = 0;
Length = (LONG)(((m_yext + 1 + CutLine) * 600) + (m_yres - 1)) / m_yres;
Length += ((GetScanSpeed()+1)*(LineOffset + 1) * 2);
//Length = 6620;
Trace(TEXT("Caculated Length for Motor stepping.. = %d (6620?)"),Length);
Trace(TEXT("ScanSpeed used.. = %d"),GetScanSpeed());
Register7 = HIBYTE(Length);
Register8 = LOBYTE(Length);
if(!WriteRegister(7,Register7))
return FALSE;
if(!WriteRegister(8,Register8))
return FALSE;
((E3_REG26*)&Register26)->Stop = 0x08;
((E3_REG26*)&Register26)->Start = (BYTE)1;
if(!WriteRegister(26,Register26))
return FALSE;
((E3_REG4*)&Register4)->WaitDelay = 1; // USB models
if(!WriteRegister(4,Register4))
return FALSE;
return TRUE;
}
VOID CPMXE3::GrayScaleToThreshold(LPBYTE lpSrc, LPBYTE lpDst, LONG RowBytes)
{
//
// code is borrowed from Visioneer scanner driver
// could be optimized.
//
BYTE val = 0;
BYTE nValueBW = 0;
INT nCount1 = 0;
INT nCount = 0;
INT LineArtThreshold = 110;
for(nCount = 0, nCount1 = 0, nValueBW = 0;nCount < RowBytes; nCount++) {
val = *(lpSrc + nCount);
if(val > LineArtThreshold)
nValueBW |= 1;
if((nCount & 7)==7) {
*(lpDst+nCount1) = nValueBW;
nValueBW=0;
nCount1++;
} else
nValueBW = nValueBW << 1;
}
if((nCount&7)!=0) {
nValueBW=nValueBW << ( 8 - (nCount & 7));
*(lpDst + nCount1) = nValueBW;
}
}
BOOL CPMXE3::GetButtonStatus(PBYTE pButtons)
{
//
// button status for 5 button scanners only
//
// this may need to be rewritten using E3_REG31
// which has Key values.
//
Register31 = 0;
INT ButtonMask = 1;
if(!ReadRegister(31,&Register31))
return FALSE;
for(INT index = 0; index < 5 ; index++){
if(Register31&ButtonMask)
pButtons[index] = 1;
else
pButtons[index] = 0;
ButtonMask<<=1;
}
if(Register31&0x01)
pButtons[6] = 1;
return TRUE;
}
BOOL CPMXE3::ClearButtonPress()
{
Register31 = 0;
if(!WriteRegister(31,Register31))
return FALSE;
return TRUE;
}
BOOL CPMXE3::WakeupScanner()
{
//
// turn on lamp
// and turn on motor power
//
if(!Lamp(TRUE))
return FALSE;
return Motor(TRUE);
}
BOOL CPMXE3::SleepScanner()
{
//
// turn off the lamp
// and turn of the motor power
//
if(!Lamp(FALSE))
return FALSE;
return Motor(FALSE);
}
BOOL CPMXE3::StartScan()
{
if(!ResetFIFO())
return FALSE;
if(!Lamp(TRUE))
return FALSE;
// DownLoadLUT ??
if(!SetXandYResolution())
return FALSE;
//
// settings commit is done at scan time
//
if(!SetScanWindow())
return FALSE;
if(!ReadRegister(13,&Register13))
return FALSE;
((E3_REG13*)&Register13)->Sdo = 0;
((E3_REG13*)&Register13)->Sclk = 1;
if(!WriteRegister(13,Register13))
return FALSE;
if(!ReadRegister(6,&Register6))
return FALSE;
if(!ReadRegister(9,&Register9))
return FALSE;
if(!ReadRegister(27,&Register27))
return FALSE;
((E3_REG6*)&Register6)->LineOffset = 1;
if(!WriteRegister(6,Register6))
return FALSE;
((E3_REG4*)&Register4)->ScanMode = m_scanmode; // changes for data type
((E3_REG4*)&Register4)->YTable = 1;
if(!WriteRegister(4,Register4))
return FALSE;
((E3_REG27*)&Register27)->True16Bits = 0;
((E3_REG27*)&Register27)->AutoPattern = 0;
if(!WriteRegister(27,Register27))
return FALSE;
INT TriggerPeriod = 5700;
Register10 = HIBYTE(TriggerPeriod);
Register11 = LOBYTE(TriggerPeriod);
if(!WriteRegister(10,Register10))
return FALSE;
if(!WriteRegister(11,Register11))
return FALSE;
((E3_REG3*)&Register3)->ScanSpeed = GetScanSpeed();
if(!WriteRegister(3,Register3))
return FALSE;
((E3_REG6*)&Register6)->FullHalf = 0;
((E3_REG6*)&Register6)->Operation = 0;
if(!WriteRegister(6,Register6))
return FALSE;
Register9 = (BYTE)10; // backstep
if(!WriteRegister(9,Register9))
return FALSE;
((E3_REG6*)&Register6)->Operation = 0;
if(!WriteRegister(6,Register6))
return FALSE;
((E3_REG6*)&Register6)->MotorPower = 1;
((E3_REG6*)&Register6)->Operation = 4; // scan
if(!WriteRegister(6,Register6))
return FALSE;
// clear buttons
if(!ClearButtonPress())
return FALSE;
Register25 = 0x10; // GIO?
if(!WriteRegister(25,Register25))
return FALSE;
return TRUE;
}
BOOL CPMXE3::ResetFIFO()
{
for(INT nResetTimes = 0; nResetTimes < 2;nResetTimes++){
StopMode();
if(!ReadRegister(3,&Register3))
return FALSE;
((E3_REG3*)&Register3)->FifoReset = 0;
if(!WriteRegister(3,Register3))
return FALSE;
((E3_REG3*)&Register3)->FifoReset = 1;
if(!WriteRegister(3,Register3))
return FALSE;
}
return TRUE;
}
BOOL CPMXE3::InitADC()
{
if(!ReadRegister(5,&Register5))
return FALSE;
((E3_REG5*)&Register5)->Adc1210 = 1;
((E3_REG5*)&Register5)->Afe = 0;
((E3_REG5*)&Register5)->Sensor_Res = 1; // 600dpi model
((E3_REG5*)&Register5)->Sensor = 0x02;
if(!WriteRegister(5,Register5))
return FALSE;
Register25 = 0x14;
if(!WriteRegister(25,Register25))
return FALSE;
if(!ClearButtonPress())
return FALSE;
/*
BYTE RDark = 0x000000be;
BYTE GDark = 0x000000be;
BYTE BDark = 0x000000be;
E3_WriteWm(1,0x03);
E3_WriteWm(2,0x04);
E3_WriteWm(3,0x22);
E3_WriteWm(5,0x12);
E3_WriteWm(0x20,(unsigned char)gRDark); //Red channel Dark Value
E3_WriteWm(0x21,(unsigned char)gGDark); //Green channel Dark Value
E3_WriteWm(0x22,(unsigned char)gBDark); //Blue channel Dark Value
E3_WriteWm(0x27,0x00);
E3_WriteWm(0x2b,0x02); //global Gain Value
*/
((E3_REG13*)&Register13)->WmVsamp = 1;
if(!WriteRegister(13,Register13))
return FALSE;
return TRUE;
}
BOOL CPMXE3::Scan()
{
//
// check carriage position (needs to be in HOME, for a proper scan)
//
if (!IsCarriageHOME()) {
if (!HomeCarriage())
return FALSE;
}
if(!StopMode())
return FALSE;
if(!InitADC())
return FALSE;
if(!MoveCarriage(TRUE,CALIBRATION_STEPSIZE)) // calibration offset position
return FALSE;
if(!MoveCarriage(TRUE,SCAN_STARTPOS_STEPSIZE)) // scan start position
return FALSE;
if(!StopMode())
return FALSE;
if(!StartScan())
return FALSE;
LONG lBytesRead = 1;
DWORD dwTotalImageSize = 0;
DWORD dwbpp = 0;
DWORD BytesPerLine = 0;
switch(m_datatype){
case 0:
dwbpp = 1;
BytesPerLine = ((m_xext +7)/8);
dwTotalImageSize = (BytesPerLine * m_yext);
break;
case 1:
dwbpp = 8;
BytesPerLine = m_xext;
dwTotalImageSize = (m_xext * m_yext);
break;
case 2:
dwbpp = 24;
BytesPerLine = (m_xext * 3);
dwTotalImageSize = ((m_xext * m_yext) * 3);
break;
default:
return FALSE;
break;
}
//
// setup data dumper, so we can see if the image needs
// work.
//
DATA_DESCRIPTION DataDesc;
DataDesc.dwbpp = dwbpp;
DataDesc.dwDataSize = dwTotalImageSize;
DataDesc.dwHeight = m_yext;
DataDesc.dwWidth = m_xext;
DataDesc.pRawData = (PBYTE)LocalAlloc(LPTR,DataDesc.dwDataSize + 1024);
PBYTE pbuffer = DataDesc.pRawData;
Trace(TEXT("Total bytes to Read: = %d"),dwTotalImageSize);
Trace(TEXT("Data BYTES PER LINE = %d"),BytesPerLine);
LONG NumLinesToRead = (65535)/BytesPerLine;
DWORD dwImageDataRead = 0;
DWORD dwTotalLinesRead = 0;
DWORD dwTotalBytesRead = 0;
while (dwImageDataRead < dwTotalImageSize) {
//
// Send request for chunk
//
/*
BYTE pRegisters[64];
memset(pRegisters,0,sizeof(pRegisters));
pRegisters[0] = CMD_GETIMAGE;
pRegisters[1] = (BYTE)NumLinesToRead; // 255 or less
pRegisters[2] = HIBYTE(BytesPerLine);
pRegisters[3] = LOBYTE(BytesPerLine);
if (!RawWrite(m_pDeviceControl->BulkInPipeIndex,pRegisters,64,0))
return FALSE;
*/
DWORD cbRet = 0;
BOOL bSuccess = FALSE;
IO_BLOCK IoBlock;
BYTE Command[8];
Command[0] = 0;
Command[1] = 0xc;
Command[2] = 128;
Command[3] = 0;
Command[4] = LOBYTE(BytesPerLine);
Command[5] = HIBYTE(BytesPerLine);
Command[6] = LOBYTE(NumLinesToRead);
Command[7] = HIBYTE(NumLinesToRead);
IoBlock.uOffset = (BYTE)IOCTL_READ_WRITE_DATA;
IoBlock.uLength = (BYTE)8;
IoBlock.pbyData = Command;
Trace(TEXT("Issuing DeviceIOControl() call request for more data..."));
bSuccess = DeviceIoControl(m_pDeviceControl->DeviceIOHandles[m_pDeviceControl->BulkInPipeIndex],
(DWORD) IOCTL_WRITE_REGISTERS,
&IoBlock,
sizeof(IO_BLOCK),
NULL,
0,
&cbRet,
NULL);
//
// read scanned data until requested chunk is recieved
//
LONG LinesRead = 0;
lBytesRead = 0;
Trace(TEXT("Requesting %d BYTES from device"),(BytesPerLine * NumLinesToRead));
if (!RawRead(m_pDeviceControl->BulkOutPipeIndex,pbuffer,(BytesPerLine * NumLinesToRead),&lBytesRead,0)) {
MessageBox(NULL,TEXT("Reading data band failed"),TEXT(""),MB_OK);
return FALSE;
}
dwTotalBytesRead += lBytesRead;
pbuffer += lBytesRead;
dwTotalLinesRead += (lBytesRead/BytesPerLine);
if((m_yext - dwTotalLinesRead) < (DWORD)NumLinesToRead){
NumLinesToRead = (m_yext - dwTotalLinesRead);
}
Trace(TEXT("Total Lines Read %d of %d"),dwTotalLinesRead,m_yext);
if (lBytesRead == 0) {
MessageBox(NULL,TEXT("No data returned from Read call"),TEXT(""),MB_OK);
return FALSE;
}
Trace(TEXT("Recieved %d BYTES from device"),lBytesRead);
//
// increment buffers/counters
//
Sleep(400);
dwImageDataRead += dwTotalBytesRead;
dwTotalBytesRead = 0;
Trace(TEXT("Total Bytes Read So Far: = %d"),dwImageDataRead);
}
StopScan();
HomeCarriage();
CDATADUMP Data;
Data.DumpDataToBitmap(TEXT("PMXE3.BMP"),&DataDesc);
if(NULL != DataDesc.pRawData)
LocalFree(DataDesc.pRawData);
return TRUE;
}
BOOL CPMXE3::RawWrite(LONG lPipeNum,BYTE *pbuffer,LONG lbuffersize,LONG lTimeout)
{
DWORD dwBytesWritten = 0;
BOOL bSuccess = TRUE;
OVERLAPPED Overlapped;
memset(&Overlapped,0,sizeof(OVERLAPPED));
bSuccess = WriteFile(m_pDeviceControl->DeviceIOHandles[lPipeNum],
pbuffer,
lbuffersize,
&dwBytesWritten,
&Overlapped);
if(dwBytesWritten < (ULONG)lbuffersize)
return FALSE;
return bSuccess;
}
BOOL CPMXE3::RawRead(LONG lPipeNum,BYTE *pbuffer,LONG lbuffersize,LONG *plbytesread,LONG lTimeout)
{
DWORD dwBytesRead = 0;
OVERLAPPED Overlapped;
memset(&Overlapped,0,sizeof(OVERLAPPED));
BOOL bSuccess = ReadFile(m_pDeviceControl->DeviceIOHandles[lPipeNum],
pbuffer,
lbuffersize,
&dwBytesRead,
&Overlapped);
*plbytesread = dwBytesRead;
return bSuccess;
}
VOID CPMXE3::Trace(LPCTSTR format,...)
{
TCHAR Buffer[1024];
va_list arglist;
va_start(arglist, format);
wvsprintf(Buffer, format, arglist);
va_end(arglist);
OutputDebugString(Buffer);
OutputDebugString(TEXT("\n"));
}