Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1209 lines
29 KiB

  1. #include "stdafx.h"
  2. #include "pmxe3.h"
  3. #include "datadump.h"
  4. CPMXE3::CPMXE3(PDEVCTRL pDeviceControl)
  5. {
  6. m_pDeviceControl = pDeviceControl;
  7. m_scanmode = scHalftone;
  8. InitializeRegisters();
  9. }
  10. CPMXE3::~CPMXE3()
  11. {
  12. }
  13. VOID CPMXE3::InitializeRegisters()
  14. {
  15. Register0 =0x00;
  16. //Register1 =0x5a;
  17. //Register2 =0x00;
  18. Register3 =0x0f;
  19. Register4 =0x32;
  20. Register5 =0x14;
  21. Register6 =0x95;
  22. Register7 =0x07;
  23. Register8 =0xd0;
  24. Register9 =0x0a;
  25. Register10=0x0f;
  26. Register11=0xa0;
  27. Register12=0x40;
  28. Register13=0x80;
  29. //Register14=0x00;
  30. //Register15=0x00;
  31. //Register16=0x00;
  32. //Register17=0x00;
  33. //Register18=0x00;
  34. //Register19=0x00;
  35. Register20=0x00;
  36. Register21=0x00;
  37. Register22=0x13;
  38. Register23=0xec;
  39. //Register24=0xff;
  40. Register25=0x14;
  41. Register26=0x18;
  42. Register27=0x11;
  43. Register28=0x2c;
  44. Register29=0x2c;
  45. //Register30=0x00;
  46. Register31=0x00;
  47. //Register32=0x00;
  48. //Register33=0x00;
  49. //Register34=0x00;
  50. //Register35=0x00;
  51. #ifdef DEBUG
  52. Trace(TEXT("Register Dump - At InitRegisters() Call"));
  53. DebugDumpRegisters();
  54. #endif
  55. }
  56. VOID CPMXE3::DebugDumpRegisters()
  57. {
  58. //
  59. // dump Init registers initial values
  60. //
  61. WORD CarriageStep = MAKEWORD(Register8,Register7); // 2000
  62. WORD ScanAreaStart = MAKEWORD(Register21,Register20); // 0
  63. WORD ScanAreaWidth = MAKEWORD(Register23,Register22); // 5100
  64. WORD XResolution = MAKEWORD(Register28,((E3_REG27*)&Register27)->XRes); // 300 dpi
  65. WORD YResolution = MAKEWORD(Register29,((E3_REG27*)&Register27)->YRes); // 300 dpi
  66. WORD TriggerPeriod = MAKEWORD(Register11,Register10); // 4000
  67. Trace(TEXT("- WORD constructed Register values -"));
  68. Trace(TEXT("Carriage Step: %d"),CarriageStep);
  69. Trace(TEXT("ScanAreaStart: %d"),ScanAreaStart);
  70. Trace(TEXT("ScanAreaWidth: %d"),ScanAreaWidth);
  71. Trace(TEXT("XResolution: %d"),XResolution);
  72. Trace(TEXT("YResolution: %d"),YResolution);
  73. Trace(TEXT("TriggerPeriod %d"),TriggerPeriod);
  74. Trace(TEXT("------------------------------------"));
  75. E3_REG3* pRegister3 = (E3_REG3*)&Register3;
  76. Trace(TEXT("- Register3 -"));
  77. Trace(TEXT("EppUsb = %d"),pRegister3->EppUsb);
  78. Trace(TEXT("FifoReset = %d"),pRegister3->FifoReset);
  79. Trace(TEXT("ScanSpeed = %d"),pRegister3->ScanSpeed);
  80. Trace(TEXT("SelfTest = %d"),pRegister3->SelfTest);
  81. Trace(TEXT("SystemReset = %d"),pRegister3->SystemReset);
  82. Trace(TEXT("WatchDog = %d"),pRegister3->WatchDog);
  83. Trace(TEXT("----------------"));
  84. E3_REG4* pRegister4 = (E3_REG4*)&Register4;
  85. Trace(TEXT("- Register4 -"));
  86. Trace(TEXT("AsicTest = %d"),pRegister4->AsicTest);
  87. Trace(TEXT("Refresh = %d"),pRegister4->Refresh);
  88. Trace(TEXT("RefreshForever = %d"),pRegister4->RefreshForever);
  89. Trace(TEXT("ScanMode = %d"),pRegister4->ScanMode);
  90. Trace(TEXT("WaitDelay = %d"),pRegister4->WaitDelay);
  91. Trace(TEXT("YTable = %d"),pRegister4->YTable);
  92. Trace(TEXT("----------------"));
  93. E3_REG5* pRegister5 = (E3_REG5*)&Register5;
  94. Trace(TEXT("- Register5 -"));
  95. Trace(TEXT("Adc1210 = %d"),pRegister5->Adc1210);
  96. Trace(TEXT("Afe = %d"),pRegister5->Afe);
  97. Trace(TEXT("Sensor = %d"),pRegister5->Sensor);
  98. Trace(TEXT("Sensor_Res = %d"),pRegister5->Sensor_Res);
  99. Trace(TEXT("----------------"));
  100. E3_REG6* pRegister6 = (E3_REG6*)&Register6;
  101. Trace(TEXT("- Register6 -"));
  102. Trace(TEXT("FullHalf = %d"),pRegister6->FullHalf);
  103. Trace(TEXT("LineOffset = %d"),pRegister6->LineOffset);
  104. Trace(TEXT("MotorPower = %d"),pRegister6->MotorPower);
  105. Trace(TEXT("Operation = %d"),pRegister6->Operation);
  106. Trace(TEXT("----------------"));
  107. E3_REG12* pRegister12 = (E3_REG12*)&Register12;
  108. Trace(TEXT("- Register12 -"));
  109. Trace(TEXT("FifoEmpty = %d"),pRegister12->FifoEmpty);
  110. Trace(TEXT("FinishFlag = %d"),pRegister12->FinishFlag);
  111. Trace(TEXT("HomeSensor = %d"),pRegister12->HomeSensor);
  112. Trace(TEXT("HwSelfTest = %d"),pRegister12->HwSelfTest);
  113. Trace(TEXT("Lamp = %d"),pRegister12->Lamp);
  114. Trace(TEXT("MotorMove = %d"),pRegister12->MotorMove);
  115. Trace(TEXT("MotorStop = %d"),pRegister12->MotorStop);
  116. Trace(TEXT("ScanStatus = %d"),pRegister12->ScanStatus);
  117. Trace(TEXT("----------------"));
  118. E3_REG13* pRegister13 = (E3_REG13*)&Register13;
  119. Trace(TEXT("- Register13 -"));
  120. Trace(TEXT("Cs = %d"),pRegister13->Cs);
  121. Trace(TEXT("Reserved = %d"),pRegister13->Reserved);
  122. Trace(TEXT("Sclk = %d"),pRegister13->Sclk);
  123. Trace(TEXT("Sdi = %d"),pRegister13->Sdi);
  124. Trace(TEXT("Sdo = %d"),pRegister13->Sdo);
  125. Trace(TEXT("WmVsamp = %d"),pRegister13->WmVsamp);
  126. Trace(TEXT("----------------"));
  127. E3_REG26* pRegister26 = (E3_REG26*)&Register26;
  128. Trace(TEXT("- Register26 -"));
  129. Trace(TEXT("Start = %d"),pRegister26->Start);
  130. Trace(TEXT("Stop = %d"),pRegister26->Stop);
  131. Trace(TEXT("----------------"));
  132. E3_REG31* pRegister31 = (E3_REG31*)&Register31;
  133. Trace(TEXT("- Register31 -"));
  134. Trace(TEXT("Key0 = %d"),pRegister31->Key0);
  135. Trace(TEXT("Key1 = %d"),pRegister31->Key1);
  136. Trace(TEXT("Key2 = %d"),pRegister31->Key2);
  137. Trace(TEXT("Key3 = %d"),pRegister31->Key3);
  138. Trace(TEXT("Key4 = %d"),pRegister31->Key4);
  139. Trace(TEXT("Key5 = %d"),pRegister31->Key5);
  140. Trace(TEXT("Key6 = %d"),pRegister31->Key6);
  141. Trace(TEXT("Key7 = %d"),pRegister31->Key7);
  142. Trace(TEXT("----------------"));
  143. Trace(TEXT("--- END REGISTER DUMP ---"));
  144. }
  145. BOOL CPMXE3::WriteRegister(INT RegisterNumber, BYTE Value)
  146. {
  147. DWORD cbRet = 0;
  148. BOOL bSuccess = FALSE;
  149. BYTE pData[2];
  150. pData[0] = BYTE(RegisterNumber);
  151. pData[1] = Value;
  152. IO_BLOCK IoBlock;
  153. IoBlock.uOffset = (BYTE)IOCTL_EPP_WRITE;
  154. IoBlock.uLength = 2;
  155. IoBlock.pbyData = pData;
  156. bSuccess = DeviceIoControl(m_pDeviceControl->DeviceIOHandles[m_pDeviceControl->BulkInPipeIndex],
  157. (DWORD) IOCTL_WRITE_REGISTERS,
  158. &IoBlock,
  159. sizeof(IO_BLOCK),
  160. NULL,
  161. 0,
  162. &cbRet,
  163. NULL);
  164. return bSuccess;
  165. }
  166. BOOL CPMXE3::WriteRegisterEx(INT RegisterNumber, BYTE Value)
  167. {
  168. BYTE pbuffer[64];
  169. memset(pbuffer,0,sizeof(pbuffer));
  170. pbuffer[0] = CMD_WRITE;
  171. pbuffer[1] = (BYTE)RegisterNumber;
  172. pbuffer[2] = 0; // length: low byte
  173. pbuffer[3] = 1; // length: high byte
  174. pbuffer[4] = Value;
  175. return RawWrite(m_pDeviceControl->BulkInPipeIndex,
  176. pbuffer,
  177. 64,
  178. 0);
  179. }
  180. BOOL CPMXE3::ReadRegister(INT RegisterNumber, BYTE *pValue)
  181. {
  182. DWORD cbRet = 0;
  183. BOOL bSuccess = FALSE;
  184. IO_BLOCK IoBlock;
  185. IoBlock.uOffset = MAKEWORD(IOCTL_EPP_READ, (BYTE)RegisterNumber);
  186. IoBlock.uLength = 1;
  187. IoBlock.pbyData = pValue;
  188. bSuccess = DeviceIoControl(m_pDeviceControl->DeviceIOHandles[m_pDeviceControl->BulkOutPipeIndex],
  189. (DWORD) IOCTL_READ_REGISTERS,
  190. (PVOID)&IoBlock,
  191. (DWORD)sizeof(IO_BLOCK),
  192. (PVOID)pValue,
  193. (DWORD)sizeof(BYTE),
  194. &cbRet,
  195. NULL);
  196. return bSuccess;
  197. }
  198. BOOL CPMXE3::ReadRegisterEx(INT RegisterNumber, BYTE *pValue)
  199. {
  200. BYTE pbuffer[64];
  201. memset(pbuffer,0,sizeof(pbuffer));
  202. pbuffer[0] = CMD_READ;
  203. pbuffer[1] = (BYTE)RegisterNumber;
  204. pbuffer[2] = 0; // length: low byte
  205. pbuffer[3] = 1; // length: high byte
  206. LONG BytesRead = 0;
  207. *pValue = 0;
  208. if(!RawWrite(m_pDeviceControl->BulkInPipeIndex, pbuffer, 64, 0)){
  209. return FALSE;
  210. }
  211. if(!RawRead(m_pDeviceControl->BulkOutPipeIndex, pbuffer, 64, &BytesRead,0)){
  212. return FALSE;
  213. }
  214. *pValue = pbuffer[0];
  215. return TRUE;
  216. }
  217. BOOL CPMXE3::SetXRes(LONG xRes)
  218. {
  219. m_xres = xRes;
  220. return TRUE;
  221. }
  222. BOOL CPMXE3::SetYRes(LONG yRes)
  223. {
  224. m_yres = yRes;
  225. return TRUE;
  226. }
  227. BOOL CPMXE3::SetXPos(LONG xPos)
  228. {
  229. m_xpos = xPos;
  230. return TRUE;
  231. }
  232. BOOL CPMXE3::SetYPos(LONG yPos)
  233. {
  234. m_ypos = yPos;
  235. return TRUE;
  236. }
  237. BOOL CPMXE3::SetXExt(LONG xExt)
  238. {
  239. m_xext = xExt;
  240. return TRUE;
  241. }
  242. BOOL CPMXE3::SetYExt(LONG yExt)
  243. {
  244. m_yext = yExt;
  245. return TRUE;
  246. }
  247. BOOL CPMXE3::SetDataType(LONG DataType)
  248. {
  249. m_datatype = DataType;
  250. switch (m_datatype) {
  251. case 0: // WIA_DATA_THRESHOLD
  252. m_scanmode = scHalftone;
  253. break;
  254. case 1: // WIA_DATA_GRAYSCALE
  255. m_scanmode = scGrayScale;
  256. break;
  257. case 2: // WIA_DATA_COLOR
  258. m_scanmode = scFullColor;
  259. break;
  260. default:
  261. return FALSE;
  262. break;
  263. }
  264. return TRUE;
  265. }
  266. ///////////////////////
  267. // //
  268. // DEVICE OPERATIONS //
  269. // //
  270. ///////////////////////
  271. BOOL CPMXE3::Lamp(BOOL bON)
  272. {
  273. if(!ReadRegister(12,&Register12))
  274. return FALSE;
  275. if(bON) // lamp ON
  276. ((E3_REG12*)&Register12)->Lamp = 1;
  277. else // lamp OFF
  278. ((E3_REG12*)&Register12)->Lamp = 0;
  279. if(!WriteRegister(12,Register12))
  280. return FALSE;
  281. return TRUE;
  282. }
  283. BOOL CPMXE3::IsLampON()
  284. {
  285. if(!ReadRegister(12,&Register12))
  286. return FALSE;
  287. if (((E3_REG12*)&Register12)->Lamp == 1)
  288. return TRUE;
  289. return FALSE;
  290. }
  291. BOOL CPMXE3::Motor(BOOL bON)
  292. {
  293. if(!ReadRegister(6,&Register6))
  294. return FALSE;
  295. if(bON){ // Turn Motor ON
  296. ((E3_REG6*)&Register6)->MotorPower = 1;
  297. } else { // Turn Motor OFF
  298. ((E3_REG6*)&Register6)->MotorPower = 0;
  299. }
  300. if(!WriteRegister(6,Register6))
  301. return FALSE;
  302. return TRUE;
  303. }
  304. BOOL CPMXE3::HomeCarriage()
  305. {
  306. StopScan(); // must issue a STOP before homing carriage...or the device makes
  307. // a rather nasty grinding noise...("That can't be good.." -Cooper Partin, May 19,2000)
  308. INT TriggerPeriod = 0;
  309. INT ScanSpeed = 7;
  310. INT OverCLK = 2; // perfect for E3 series models
  311. INT ExposureTimeMin = 2000; // 2 seconds exposure time
  312. INT ExposureTime = 12000; // possible choices, (13800,5610,11400,12000)
  313. //
  314. // calculate TriggerPeriod
  315. //
  316. if((ExposureTime / ( ScanSpeed + 1 ) ) * OverCLK < ExposureTimeMin * OverCLK)
  317. TriggerPeriod = (INT)(ExposureTimeMin * OverCLK);
  318. else
  319. TriggerPeriod = (INT)((ExposureTime / ( ScanSpeed + 1 ) ) * OverCLK);
  320. Register25 = 0x14;
  321. if(!WriteRegister(25,Register25))
  322. return FALSE;
  323. if(!SetMotorSpeed(TriggerPeriod,ScanSpeed))
  324. return FALSE;
  325. if(!ReadRegister(6,&Register6))
  326. return FALSE;
  327. if(!StopMode())
  328. return FALSE;
  329. ((E3_REG6*)&Register6)->MotorPower = 1; // motor ON
  330. ((E3_REG6*)&Register6)->Operation = 5; // auto home
  331. if(!WriteRegister(6,Register6))
  332. return FALSE;
  333. //
  334. // Prevent any operations until scanner is in HOME position...
  335. // If any operations are done... could result in nasty noises
  336. // and system hangs... :) (just like forcing a car into reverse, while
  337. // driving down the freeway...)
  338. //
  339. while(!IsCarriageHOME()) {
  340. Sleep(100);
  341. }
  342. return TRUE;
  343. }
  344. BOOL CPMXE3::StopMode()
  345. {
  346. ((E3_REG6*)&Register6)->Operation = 0;
  347. return WriteRegister(6,Register6);
  348. }
  349. BOOL CPMXE3::WriteStopImageRegister()
  350. {
  351. BYTE pbuffer[64];
  352. memset(pbuffer,0,sizeof(pbuffer));
  353. pbuffer[0] = CMD_STOPIMAGE;
  354. return RawWrite(m_pDeviceControl->BulkInPipeIndex,
  355. pbuffer,
  356. 64,
  357. 0);
  358. }
  359. BOOL CPMXE3::StopScan()
  360. {
  361. if(!WriteStopImageRegister())
  362. return FALSE;
  363. if(!ReadRegister(6,&Register6))
  364. return FALSE;
  365. ((E3_REG6*)&Register6)->MotorPower = 0;
  366. ((E3_REG6*)&Register6)->Operation = 0;
  367. if(!WriteRegister(6,Register6))
  368. return FALSE;
  369. ((E3_REG13*)&Register13)->Sdo = 0;
  370. ((E3_REG13*)&Register13)->Sclk = 0;
  371. if(!WriteRegister(13,Register13))
  372. return FALSE;
  373. Register25 = 0x14;
  374. if(!WriteRegister(25,Register25))
  375. return FALSE;
  376. return TRUE;
  377. }
  378. BOOL CPMXE3::SetMotorSpeed(INT TriggerPeriod, INT ScanSpeed)
  379. {
  380. //
  381. // set trigger period
  382. //
  383. Register10 = HIBYTE(TriggerPeriod/2);
  384. Register11 = LOBYTE(TriggerPeriod/2);
  385. if(!WriteRegister(10,Register10))
  386. return FALSE;
  387. if(!WriteRegister(11,Register11))
  388. return FALSE;
  389. //
  390. // set scan speed
  391. //
  392. // Register3 = 0;
  393. if(!ReadRegister(3,&Register3))
  394. return FALSE;
  395. ((E3_REG3*)&Register3)->ScanSpeed = ScanSpeed;
  396. if(!WriteRegister(3,Register3))
  397. return FALSE;
  398. //
  399. // initialize motor
  400. //
  401. // Register6 = 0;
  402. ((E3_REG6*)&Register6)->MotorPower = 1;
  403. ((E3_REG6*)&Register6)->FullHalf = 1;
  404. ((E3_REG6*)&Register6)->Operation = 0;
  405. if(!WriteRegister(6,Register6))
  406. return FALSE;
  407. return TRUE;
  408. }
  409. BOOL CPMXE3::MoveCarriage(BOOL bForward, INT Steps)
  410. {
  411. INT TriggerPeriod = 0;
  412. INT ScanSpeed = 7; // perfect for E3 series models
  413. INT OverCLK = 2; // perfect for E3 series models
  414. INT ExposureTimeMin = 2000; // 2 seconds exposure time
  415. INT ExposureTime = 12000; // possible choices, (13800,5610,11400,12000)
  416. //
  417. // calculate TriggerPeriod
  418. //
  419. if((ExposureTime / ( ScanSpeed + 1 ) ) * OverCLK < ExposureTimeMin * OverCLK)
  420. TriggerPeriod = (INT)(ExposureTimeMin * OverCLK);
  421. else
  422. TriggerPeriod = (INT)((ExposureTime / ( ScanSpeed + 1 ) ) * OverCLK);
  423. if(!SetMotorSpeed(TriggerPeriod,ScanSpeed))
  424. return FALSE;
  425. Register7 = HIBYTE(Steps*2); // high byte (move step)
  426. Register8 = LOBYTE(Steps*2); // low byte (move step)
  427. if(!WriteRegister(7,Register7))
  428. return FALSE;
  429. if(!WriteRegister(8,Register8))
  430. return FALSE;
  431. if(!StopMode())
  432. return FALSE;
  433. if(!ReadRegister(6,&Register6))
  434. return FALSE;
  435. ((E3_REG6*)&Register6)->MotorPower = 1;
  436. if(bForward) // move forward
  437. ((E3_REG6*)&Register6)->Operation = 2;
  438. else // move backward
  439. ((E3_REG6*)&Register6)->Operation = 3;
  440. if(!WriteRegister(6,Register6))
  441. return FALSE;
  442. return TRUE;
  443. }
  444. BOOL CPMXE3::IsCarriageHOME()
  445. {
  446. ReadRegister(12,&Register12);
  447. if((Register12&CARRIAGE_HOME) != CARRIAGE_HOME)
  448. return FALSE;
  449. return TRUE;
  450. }
  451. BOOL CPMXE3::IsMotorBusy()
  452. {
  453. ReadRegister(12,&Register12);
  454. if((Register12&MOTOR_BUSY) != MOTOR_BUSY)
  455. return TRUE;
  456. return FALSE;
  457. }
  458. INT CPMXE3::GetScanSpeed()
  459. {
  460. //
  461. // return a preferred scan speed, with respect to
  462. // the current y resolution.
  463. //
  464. if (m_yres>300)
  465. return 0;
  466. else if(m_yres>200)
  467. return 1;
  468. else if(m_yres>150)
  469. return 2;
  470. else if(m_yres>100)
  471. return 3;
  472. else if(m_yres>75)
  473. return 5;
  474. else if(m_yres>0)
  475. return 7;
  476. return 0;
  477. }
  478. BOOL CPMXE3::SetXandYResolution()
  479. {
  480. //
  481. // X and Y resolution have to be set at the same time..
  482. //
  483. if(!ReadRegister(27,&Register27)){
  484. return FALSE;
  485. }
  486. if(!ReadRegister(28,&Register28)){
  487. return FALSE;
  488. }
  489. if(!ReadRegister(29,&Register29)){
  490. return FALSE;
  491. }
  492. ((E3_REG27*)&Register27)->XRes = HIBYTE(m_xres);
  493. ((E3_REG28*)&Register28)->XRes = LOBYTE(m_xres);
  494. ((E3_REG27*)&Register27)->YRes = HIBYTE(m_yres);
  495. ((E3_REG29*)&Register29)->YRes = LOBYTE(m_yres);
  496. if(!WriteRegister(27,Register27)){
  497. return FALSE;
  498. }
  499. if(!WriteRegister(28,Register28)){
  500. return FALSE;
  501. }
  502. if(!WriteRegister(29,Register29)){
  503. return FALSE;
  504. }
  505. return TRUE;
  506. }
  507. BOOL CPMXE3::SetScanWindow()
  508. {
  509. //
  510. // set all three (xpos,ypos,xext,and current yext)
  511. // at this point..
  512. //
  513. if(!ReadRegister(7,&Register7))
  514. return FALSE;
  515. if(!ReadRegister(8,&Register8))
  516. return FALSE;
  517. if(!ReadRegister(20,&Register20))
  518. return FALSE;
  519. if(!ReadRegister(21,&Register21))
  520. return FALSE;
  521. if(!ReadRegister(22,&Register22))
  522. return FALSE;
  523. if(!ReadRegister(23,&Register23))
  524. return FALSE;
  525. if(!ReadRegister(26,&Register26))
  526. return FALSE;
  527. if(!ReadRegister(4,&Register4))
  528. return FALSE;
  529. LONG AreaStart = m_xpos;
  530. LONG AreaStartOffset = 146; //180;
  531. AreaStart = (AreaStart * (600/*Hardware DPI*// m_xres));
  532. AreaStart += AreaStartOffset;
  533. ((E3_REG20*)&Register20)->AreaStart = HIBYTE(AreaStart);
  534. ((E3_REG21*)&Register21)->AreaStart = LOBYTE(AreaStart);
  535. if(!WriteRegister(20,Register20))
  536. return FALSE;
  537. if(!WriteRegister(21,Register21))
  538. return FALSE;
  539. ((E3_REG22*)&Register22)->AreaWidth = HIBYTE(m_xext);
  540. ((E3_REG23*)&Register23)->AreaWidth = LOBYTE(m_xext);
  541. if(!WriteRegister(22,Register22))
  542. return FALSE;
  543. if(!WriteRegister(23,Register23))
  544. return FALSE;
  545. if(!WriteRegister(27,Register27))
  546. return FALSE;
  547. if(!WriteRegister(28,Register28))
  548. return FALSE;
  549. if(!WriteRegister(29,Register29))
  550. return FALSE;
  551. LONG Length = 0;
  552. LONG CutLine = 2;
  553. LONG LineOffset = 0;
  554. Length = (LONG)(((m_yext + 1 + CutLine) * 600) + (m_yres - 1)) / m_yres;
  555. Length += ((GetScanSpeed()+1)*(LineOffset + 1) * 2);
  556. //Length = 6620;
  557. Trace(TEXT("Caculated Length for Motor stepping.. = %d (6620?)"),Length);
  558. Trace(TEXT("ScanSpeed used.. = %d"),GetScanSpeed());
  559. Register7 = HIBYTE(Length);
  560. Register8 = LOBYTE(Length);
  561. if(!WriteRegister(7,Register7))
  562. return FALSE;
  563. if(!WriteRegister(8,Register8))
  564. return FALSE;
  565. ((E3_REG26*)&Register26)->Stop = 0x08;
  566. ((E3_REG26*)&Register26)->Start = (BYTE)1;
  567. if(!WriteRegister(26,Register26))
  568. return FALSE;
  569. ((E3_REG4*)&Register4)->WaitDelay = 1; // USB models
  570. if(!WriteRegister(4,Register4))
  571. return FALSE;
  572. return TRUE;
  573. }
  574. VOID CPMXE3::GrayScaleToThreshold(LPBYTE lpSrc, LPBYTE lpDst, LONG RowBytes)
  575. {
  576. //
  577. // code is borrowed from Visioneer scanner driver
  578. // could be optimized.
  579. //
  580. BYTE val = 0;
  581. BYTE nValueBW = 0;
  582. INT nCount1 = 0;
  583. INT nCount = 0;
  584. INT LineArtThreshold = 110;
  585. for(nCount = 0, nCount1 = 0, nValueBW = 0;nCount < RowBytes; nCount++) {
  586. val = *(lpSrc + nCount);
  587. if(val > LineArtThreshold)
  588. nValueBW |= 1;
  589. if((nCount & 7)==7) {
  590. *(lpDst+nCount1) = nValueBW;
  591. nValueBW=0;
  592. nCount1++;
  593. } else
  594. nValueBW = nValueBW << 1;
  595. }
  596. if((nCount&7)!=0) {
  597. nValueBW=nValueBW << ( 8 - (nCount & 7));
  598. *(lpDst + nCount1) = nValueBW;
  599. }
  600. }
  601. BOOL CPMXE3::GetButtonStatus(PBYTE pButtons)
  602. {
  603. //
  604. // button status for 5 button scanners only
  605. //
  606. // this may need to be rewritten using E3_REG31
  607. // which has Key values.
  608. //
  609. Register31 = 0;
  610. INT ButtonMask = 1;
  611. if(!ReadRegister(31,&Register31))
  612. return FALSE;
  613. for(INT index = 0; index < 5 ; index++){
  614. if(Register31&ButtonMask)
  615. pButtons[index] = 1;
  616. else
  617. pButtons[index] = 0;
  618. ButtonMask<<=1;
  619. }
  620. if(Register31&0x01)
  621. pButtons[6] = 1;
  622. return TRUE;
  623. }
  624. BOOL CPMXE3::ClearButtonPress()
  625. {
  626. Register31 = 0;
  627. if(!WriteRegister(31,Register31))
  628. return FALSE;
  629. return TRUE;
  630. }
  631. BOOL CPMXE3::WakeupScanner()
  632. {
  633. //
  634. // turn on lamp
  635. // and turn on motor power
  636. //
  637. if(!Lamp(TRUE))
  638. return FALSE;
  639. return Motor(TRUE);
  640. }
  641. BOOL CPMXE3::SleepScanner()
  642. {
  643. //
  644. // turn off the lamp
  645. // and turn of the motor power
  646. //
  647. if(!Lamp(FALSE))
  648. return FALSE;
  649. return Motor(FALSE);
  650. }
  651. BOOL CPMXE3::StartScan()
  652. {
  653. if(!ResetFIFO())
  654. return FALSE;
  655. if(!Lamp(TRUE))
  656. return FALSE;
  657. // DownLoadLUT ??
  658. if(!SetXandYResolution())
  659. return FALSE;
  660. //
  661. // settings commit is done at scan time
  662. //
  663. if(!SetScanWindow())
  664. return FALSE;
  665. if(!ReadRegister(13,&Register13))
  666. return FALSE;
  667. ((E3_REG13*)&Register13)->Sdo = 0;
  668. ((E3_REG13*)&Register13)->Sclk = 1;
  669. if(!WriteRegister(13,Register13))
  670. return FALSE;
  671. if(!ReadRegister(6,&Register6))
  672. return FALSE;
  673. if(!ReadRegister(9,&Register9))
  674. return FALSE;
  675. if(!ReadRegister(27,&Register27))
  676. return FALSE;
  677. ((E3_REG6*)&Register6)->LineOffset = 1;
  678. if(!WriteRegister(6,Register6))
  679. return FALSE;
  680. ((E3_REG4*)&Register4)->ScanMode = m_scanmode; // changes for data type
  681. ((E3_REG4*)&Register4)->YTable = 1;
  682. if(!WriteRegister(4,Register4))
  683. return FALSE;
  684. ((E3_REG27*)&Register27)->True16Bits = 0;
  685. ((E3_REG27*)&Register27)->AutoPattern = 0;
  686. if(!WriteRegister(27,Register27))
  687. return FALSE;
  688. INT TriggerPeriod = 5700;
  689. Register10 = HIBYTE(TriggerPeriod);
  690. Register11 = LOBYTE(TriggerPeriod);
  691. if(!WriteRegister(10,Register10))
  692. return FALSE;
  693. if(!WriteRegister(11,Register11))
  694. return FALSE;
  695. ((E3_REG3*)&Register3)->ScanSpeed = GetScanSpeed();
  696. if(!WriteRegister(3,Register3))
  697. return FALSE;
  698. ((E3_REG6*)&Register6)->FullHalf = 0;
  699. ((E3_REG6*)&Register6)->Operation = 0;
  700. if(!WriteRegister(6,Register6))
  701. return FALSE;
  702. Register9 = (BYTE)10; // backstep
  703. if(!WriteRegister(9,Register9))
  704. return FALSE;
  705. ((E3_REG6*)&Register6)->Operation = 0;
  706. if(!WriteRegister(6,Register6))
  707. return FALSE;
  708. ((E3_REG6*)&Register6)->MotorPower = 1;
  709. ((E3_REG6*)&Register6)->Operation = 4; // scan
  710. if(!WriteRegister(6,Register6))
  711. return FALSE;
  712. // clear buttons
  713. if(!ClearButtonPress())
  714. return FALSE;
  715. Register25 = 0x10; // GIO?
  716. if(!WriteRegister(25,Register25))
  717. return FALSE;
  718. return TRUE;
  719. }
  720. BOOL CPMXE3::ResetFIFO()
  721. {
  722. for(INT nResetTimes = 0; nResetTimes < 2;nResetTimes++){
  723. StopMode();
  724. if(!ReadRegister(3,&Register3))
  725. return FALSE;
  726. ((E3_REG3*)&Register3)->FifoReset = 0;
  727. if(!WriteRegister(3,Register3))
  728. return FALSE;
  729. ((E3_REG3*)&Register3)->FifoReset = 1;
  730. if(!WriteRegister(3,Register3))
  731. return FALSE;
  732. }
  733. return TRUE;
  734. }
  735. BOOL CPMXE3::InitADC()
  736. {
  737. if(!ReadRegister(5,&Register5))
  738. return FALSE;
  739. ((E3_REG5*)&Register5)->Adc1210 = 1;
  740. ((E3_REG5*)&Register5)->Afe = 0;
  741. ((E3_REG5*)&Register5)->Sensor_Res = 1; // 600dpi model
  742. ((E3_REG5*)&Register5)->Sensor = 0x02;
  743. if(!WriteRegister(5,Register5))
  744. return FALSE;
  745. Register25 = 0x14;
  746. if(!WriteRegister(25,Register25))
  747. return FALSE;
  748. if(!ClearButtonPress())
  749. return FALSE;
  750. /*
  751. BYTE RDark = 0x000000be;
  752. BYTE GDark = 0x000000be;
  753. BYTE BDark = 0x000000be;
  754. E3_WriteWm(1,0x03);
  755. E3_WriteWm(2,0x04);
  756. E3_WriteWm(3,0x22);
  757. E3_WriteWm(5,0x12);
  758. E3_WriteWm(0x20,(unsigned char)gRDark); //Red channel Dark Value
  759. E3_WriteWm(0x21,(unsigned char)gGDark); //Green channel Dark Value
  760. E3_WriteWm(0x22,(unsigned char)gBDark); //Blue channel Dark Value
  761. E3_WriteWm(0x27,0x00);
  762. E3_WriteWm(0x2b,0x02); //global Gain Value
  763. */
  764. ((E3_REG13*)&Register13)->WmVsamp = 1;
  765. if(!WriteRegister(13,Register13))
  766. return FALSE;
  767. return TRUE;
  768. }
  769. BOOL CPMXE3::Scan()
  770. {
  771. //
  772. // check carriage position (needs to be in HOME, for a proper scan)
  773. //
  774. if (!IsCarriageHOME()) {
  775. if (!HomeCarriage())
  776. return FALSE;
  777. }
  778. if(!StopMode())
  779. return FALSE;
  780. if(!InitADC())
  781. return FALSE;
  782. if(!MoveCarriage(TRUE,CALIBRATION_STEPSIZE)) // calibration offset position
  783. return FALSE;
  784. if(!MoveCarriage(TRUE,SCAN_STARTPOS_STEPSIZE)) // scan start position
  785. return FALSE;
  786. if(!StopMode())
  787. return FALSE;
  788. if(!StartScan())
  789. return FALSE;
  790. LONG lBytesRead = 1;
  791. DWORD dwTotalImageSize = 0;
  792. DWORD dwbpp = 0;
  793. DWORD BytesPerLine = 0;
  794. switch(m_datatype){
  795. case 0:
  796. dwbpp = 1;
  797. BytesPerLine = ((m_xext +7)/8);
  798. dwTotalImageSize = (BytesPerLine * m_yext);
  799. break;
  800. case 1:
  801. dwbpp = 8;
  802. BytesPerLine = m_xext;
  803. dwTotalImageSize = (m_xext * m_yext);
  804. break;
  805. case 2:
  806. dwbpp = 24;
  807. BytesPerLine = (m_xext * 3);
  808. dwTotalImageSize = ((m_xext * m_yext) * 3);
  809. break;
  810. default:
  811. return FALSE;
  812. break;
  813. }
  814. //
  815. // setup data dumper, so we can see if the image needs
  816. // work.
  817. //
  818. DATA_DESCRIPTION DataDesc;
  819. DataDesc.dwbpp = dwbpp;
  820. DataDesc.dwDataSize = dwTotalImageSize;
  821. DataDesc.dwHeight = m_yext;
  822. DataDesc.dwWidth = m_xext;
  823. DataDesc.pRawData = (PBYTE)LocalAlloc(LPTR,DataDesc.dwDataSize + 1024);
  824. PBYTE pbuffer = DataDesc.pRawData;
  825. Trace(TEXT("Total bytes to Read: = %d"),dwTotalImageSize);
  826. Trace(TEXT("Data BYTES PER LINE = %d"),BytesPerLine);
  827. LONG NumLinesToRead = (65535)/BytesPerLine;
  828. DWORD dwImageDataRead = 0;
  829. DWORD dwTotalLinesRead = 0;
  830. DWORD dwTotalBytesRead = 0;
  831. while (dwImageDataRead < dwTotalImageSize) {
  832. //
  833. // Send request for chunk
  834. //
  835. /*
  836. BYTE pRegisters[64];
  837. memset(pRegisters,0,sizeof(pRegisters));
  838. pRegisters[0] = CMD_GETIMAGE;
  839. pRegisters[1] = (BYTE)NumLinesToRead; // 255 or less
  840. pRegisters[2] = HIBYTE(BytesPerLine);
  841. pRegisters[3] = LOBYTE(BytesPerLine);
  842. if (!RawWrite(m_pDeviceControl->BulkInPipeIndex,pRegisters,64,0))
  843. return FALSE;
  844. */
  845. DWORD cbRet = 0;
  846. BOOL bSuccess = FALSE;
  847. IO_BLOCK IoBlock;
  848. BYTE Command[8];
  849. Command[0] = 0;
  850. Command[1] = 0xc;
  851. Command[2] = 128;
  852. Command[3] = 0;
  853. Command[4] = LOBYTE(BytesPerLine);
  854. Command[5] = HIBYTE(BytesPerLine);
  855. Command[6] = LOBYTE(NumLinesToRead);
  856. Command[7] = HIBYTE(NumLinesToRead);
  857. IoBlock.uOffset = (BYTE)IOCTL_READ_WRITE_DATA;
  858. IoBlock.uLength = (BYTE)8;
  859. IoBlock.pbyData = Command;
  860. Trace(TEXT("Issuing DeviceIOControl() call request for more data..."));
  861. bSuccess = DeviceIoControl(m_pDeviceControl->DeviceIOHandles[m_pDeviceControl->BulkInPipeIndex],
  862. (DWORD) IOCTL_WRITE_REGISTERS,
  863. &IoBlock,
  864. sizeof(IO_BLOCK),
  865. NULL,
  866. 0,
  867. &cbRet,
  868. NULL);
  869. //
  870. // read scanned data until requested chunk is recieved
  871. //
  872. LONG LinesRead = 0;
  873. lBytesRead = 0;
  874. Trace(TEXT("Requesting %d BYTES from device"),(BytesPerLine * NumLinesToRead));
  875. if (!RawRead(m_pDeviceControl->BulkOutPipeIndex,pbuffer,(BytesPerLine * NumLinesToRead),&lBytesRead,0)) {
  876. MessageBox(NULL,TEXT("Reading data band failed"),TEXT(""),MB_OK);
  877. return FALSE;
  878. }
  879. dwTotalBytesRead += lBytesRead;
  880. pbuffer += lBytesRead;
  881. dwTotalLinesRead += (lBytesRead/BytesPerLine);
  882. if((m_yext - dwTotalLinesRead) < (DWORD)NumLinesToRead){
  883. NumLinesToRead = (m_yext - dwTotalLinesRead);
  884. }
  885. Trace(TEXT("Total Lines Read %d of %d"),dwTotalLinesRead,m_yext);
  886. if (lBytesRead == 0) {
  887. MessageBox(NULL,TEXT("No data returned from Read call"),TEXT(""),MB_OK);
  888. return FALSE;
  889. }
  890. Trace(TEXT("Recieved %d BYTES from device"),lBytesRead);
  891. //
  892. // increment buffers/counters
  893. //
  894. Sleep(400);
  895. dwImageDataRead += dwTotalBytesRead;
  896. dwTotalBytesRead = 0;
  897. Trace(TEXT("Total Bytes Read So Far: = %d"),dwImageDataRead);
  898. }
  899. StopScan();
  900. HomeCarriage();
  901. CDATADUMP Data;
  902. Data.DumpDataToBitmap(TEXT("PMXE3.BMP"),&DataDesc);
  903. if(NULL != DataDesc.pRawData)
  904. LocalFree(DataDesc.pRawData);
  905. return TRUE;
  906. }
  907. BOOL CPMXE3::RawWrite(LONG lPipeNum,BYTE *pbuffer,LONG lbuffersize,LONG lTimeout)
  908. {
  909. DWORD dwBytesWritten = 0;
  910. BOOL bSuccess = TRUE;
  911. OVERLAPPED Overlapped;
  912. memset(&Overlapped,0,sizeof(OVERLAPPED));
  913. bSuccess = WriteFile(m_pDeviceControl->DeviceIOHandles[lPipeNum],
  914. pbuffer,
  915. lbuffersize,
  916. &dwBytesWritten,
  917. &Overlapped);
  918. if(dwBytesWritten < (ULONG)lbuffersize)
  919. return FALSE;
  920. return bSuccess;
  921. }
  922. BOOL CPMXE3::RawRead(LONG lPipeNum,BYTE *pbuffer,LONG lbuffersize,LONG *plbytesread,LONG lTimeout)
  923. {
  924. DWORD dwBytesRead = 0;
  925. OVERLAPPED Overlapped;
  926. memset(&Overlapped,0,sizeof(OVERLAPPED));
  927. BOOL bSuccess = ReadFile(m_pDeviceControl->DeviceIOHandles[lPipeNum],
  928. pbuffer,
  929. lbuffersize,
  930. &dwBytesRead,
  931. &Overlapped);
  932. *plbytesread = dwBytesRead;
  933. return bSuccess;
  934. }
  935. VOID CPMXE3::Trace(LPCTSTR format,...)
  936. {
  937. TCHAR Buffer[1024];
  938. va_list arglist;
  939. va_start(arglist, format);
  940. wvsprintf(Buffer, format, arglist);
  941. va_end(arglist);
  942. OutputDebugString(Buffer);
  943. OutputDebugString(TEXT("\n"));
  944. }