summaryrefslogtreecommitdiff
path: root/backend/mustek_usb2_asic.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2014-10-06 14:00:40 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2014-10-06 14:00:40 +0200
commit6e9c41a892ed0e0da326e0278b3221ce3f5713b8 (patch)
tree2e301d871bbeeb44aa57ff9cc070fcf3be484487 /backend/mustek_usb2_asic.c
Initial import of sane-backends version 1.0.24-1.2
Diffstat (limited to 'backend/mustek_usb2_asic.c')
-rw-r--r--backend/mustek_usb2_asic.c5264
1 files changed, 5264 insertions, 0 deletions
diff --git a/backend/mustek_usb2_asic.c b/backend/mustek_usb2_asic.c
new file mode 100644
index 0000000..3019e5e
--- /dev/null
+++ b/backend/mustek_usb2_asic.c
@@ -0,0 +1,5264 @@
+/* sane - Scanner Access Now Easy.
+
+ Copyright (C) 2005 Mustek.
+ Originally maintained by Mustek
+ Author:Roy 2005.5.24
+
+ This file is part of the SANE package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, the authors of SANE give permission for
+ additional uses of the libraries contained in this release of SANE.
+
+ The exception is that, if you link a SANE library with other files
+ to produce an executable, this does not by itself cause the
+ resulting executable to be covered by the GNU General Public
+ License. Your use of that executable is in no way restricted on
+ account of linking the SANE library code into it.
+
+ This exception does not, however, invalidate any other reasons why
+ the executable file might be covered by the GNU General Public
+ License.
+
+ If you submit changes to SANE to the maintainers to be included in
+ a subsequent release, you agree by submitting the changes that
+ those changes may be distributed with this exception intact.
+
+ If you write modifications of your own for SANE, it is your choice
+ whether to permit this exception to apply to your modifications.
+ If you do not wish that, delete this exception notice.
+
+ This file implements a SANE backend for the Mustek BearPaw 2448 TA Pro
+ and similar USB2 scanners. */
+
+#include "mustek_usb2_asic.h"
+
+/* ---------------------- low level asic functions -------------------------- */
+
+static SANE_Byte RegisterBankStatus = -1;
+
+static STATUS
+WriteIOControl (PAsic chip, unsigned short wValue, unsigned short wIndex, unsigned short wLength,
+ SANE_Byte * lpbuf)
+{
+ STATUS status = STATUS_GOOD;
+
+ status =
+ sanei_usb_control_msg (chip->fd, 0x40, 0x01, wValue, wIndex, wLength,
+ lpbuf);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "WriteIOControl Error!\n");
+ return status;
+ }
+
+ return STATUS_GOOD;
+}
+
+static STATUS
+ReadIOControl (PAsic chip, unsigned short wValue, unsigned short wIndex, unsigned short wLength,
+ SANE_Byte * lpbuf)
+{
+ STATUS status = STATUS_GOOD;
+
+ status =
+ sanei_usb_control_msg (chip->fd, 0xc0, 0x01, wValue, wIndex, wLength,
+ lpbuf);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "WriteIOControl Error!\n");
+ return status;
+ }
+
+ return status;
+}
+
+static STATUS
+Mustek_ClearFIFO (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte buf[4];
+ DBG (DBG_ASIC, "Mustek_ClearFIFO:Enter\n");
+
+ buf[0] = 0;
+ buf[1] = 0;
+ buf[2] = 0;
+ buf[3] = 0;
+ status = WriteIOControl (chip, 0x05, 0, 4, (SANE_Byte *) (buf));
+ if (status != STATUS_GOOD)
+ return status;
+
+ status = WriteIOControl (chip, 0xc0, 0, 4, (SANE_Byte *) (buf));
+ if (status != STATUS_GOOD)
+ return status;
+
+
+ DBG (DBG_ASIC, "Mustek_ClearFIFO:Exit\n");
+ return STATUS_GOOD;
+}
+
+
+static STATUS
+Mustek_SendData (PAsic chip, unsigned short reg, SANE_Byte data)
+{
+ SANE_Byte buf[4];
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "Mustek_SendData: Enter. reg=%x,data=%x\n", reg, data);
+
+
+ if (reg <= 0xFF)
+ {
+ if (RegisterBankStatus != 0)
+ {
+ DBG (DBG_ASIC, "RegisterBankStatus=%d\n", RegisterBankStatus);
+ buf[0] = ES01_5F_REGISTER_BANK_SELECT;
+ buf[1] = SELECT_REGISTER_BANK0;
+ buf[2] = ES01_5F_REGISTER_BANK_SELECT;
+ buf[3] = SELECT_REGISTER_BANK0;
+ WriteIOControl (chip, 0xb0, 0, 4, buf);
+ RegisterBankStatus = 0;
+ DBG (DBG_ASIC, "RegisterBankStatus=%d\n", RegisterBankStatus);
+ }
+
+ }
+ else if (reg <= 0x1FF)
+ {
+ if (RegisterBankStatus != 1)
+ {
+ DBG (DBG_ASIC, "RegisterBankStatus=%d\n", RegisterBankStatus);
+ buf[0] = ES01_5F_REGISTER_BANK_SELECT;
+ buf[1] = SELECT_REGISTER_BANK1;
+ buf[2] = ES01_5F_REGISTER_BANK_SELECT;
+ buf[3] = SELECT_REGISTER_BANK1;
+
+ WriteIOControl (chip, 0xb0, 0, 4, buf);
+ RegisterBankStatus = 1;
+ }
+ }
+ else if (reg <= 0x2FF)
+ {
+ if (RegisterBankStatus != 2)
+ {
+ DBG (DBG_ASIC, "RegisterBankStatus=%d\n", RegisterBankStatus);
+ buf[0] = ES01_5F_REGISTER_BANK_SELECT;
+ buf[1] = SELECT_REGISTER_BANK2;
+ buf[2] = ES01_5F_REGISTER_BANK_SELECT;
+ buf[3] = SELECT_REGISTER_BANK2;
+
+ WriteIOControl (chip, 0xb0, 0, 4, buf);
+ RegisterBankStatus = 2;
+ }
+ }
+
+ buf[0] = LOBYTE (reg);
+ buf[1] = data;
+ buf[2] = LOBYTE (reg);
+ buf[3] = data;
+ status = WriteIOControl (chip, 0xb0, 0, 4, buf);
+ if (status != STATUS_GOOD)
+ DBG (DBG_ERR, ("Mustek_SendData: write error\n"));
+
+ return status;
+}
+
+static STATUS
+Mustek_ReceiveData (PAsic chip, SANE_Byte * reg)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte buf[4];
+
+ DBG (DBG_ASIC, "Mustek_ReceiveData\n");
+
+ status = ReadIOControl (chip, 0x07, 0, 4, buf);
+
+ *reg = buf[0];
+ return status;
+}
+
+static STATUS
+Mustek_WriteAddressLineForRegister (PAsic chip, SANE_Byte x)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte buf[4];
+
+ DBG (DBG_ASIC, "Mustek_WriteAddressLineForRegister: Enter\n");
+
+ buf[0] = x;
+ buf[1] = x;
+ buf[2] = x;
+ buf[3] = x;
+ status = WriteIOControl (chip, 0x04, x, 4, buf);
+
+ DBG (DBG_ASIC, "Mustek_WriteAddressLineForRegister: Exit\n");
+ return status;
+}
+
+
+static STATUS
+SetRWSize (PAsic chip, SANE_Byte ReadWrite, unsigned int size)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "SetRWSize: Enter\n");
+
+ if (ReadWrite == 0)
+ { /*write */
+ status = Mustek_SendData (chip, 0x7C, (SANE_Byte) (size));
+ if (status != STATUS_GOOD)
+ return status;
+ status = Mustek_SendData (chip, 0x7D, (SANE_Byte) (size >> 8));
+ if (status != STATUS_GOOD)
+ return status;
+ status = Mustek_SendData (chip, 0x7E, (SANE_Byte) (size >> 16));
+ if (status != STATUS_GOOD)
+ return status;
+ status = Mustek_SendData (chip, 0x7F, (SANE_Byte) (size >> 24));
+ if (status != STATUS_GOOD)
+ return status;
+ }
+ else
+ { /* read */
+ status = Mustek_SendData (chip, 0x7C, (SANE_Byte) (size >> 1));
+ if (status != STATUS_GOOD)
+ return status;
+ status = Mustek_SendData (chip, 0x7D, (SANE_Byte) (size >> 9));
+ if (status != STATUS_GOOD)
+ return status;
+ status = Mustek_SendData (chip, 0x7E, (SANE_Byte) (size >> 17));
+ if (status != STATUS_GOOD)
+ return status;
+ status = Mustek_SendData (chip, 0x7F, (SANE_Byte) (size >> 25));
+ if (status != STATUS_GOOD)
+ return status;
+ }
+
+ DBG (DBG_ASIC, "SetRWSize: Exit\n");
+ return STATUS_GOOD;
+}
+
+static STATUS
+Mustek_DMARead (PAsic chip, unsigned int size, SANE_Byte * lpdata)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned int i, buf[1];
+ unsigned int read_size;
+
+ DBG (DBG_ASIC, "Mustek_DMARead: Enter\n");
+
+ status = Mustek_ClearFIFO (chip);
+ if (status != STATUS_GOOD)
+ return status;
+
+ buf[0] = read_size = 32 * 1024;
+ for (i = 0; i < size / (read_size); i++)
+ {
+ SetRWSize (chip, 1, buf[0]);
+ status = WriteIOControl (chip, 0x03, 0, 4, (SANE_Byte *) (buf));
+
+ status =
+ sanei_usb_read_bulk (chip->fd, lpdata + i * read_size,
+ (size_t *) buf);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Mustek_DMARead: read error\n");
+ return status;
+ }
+ }
+
+ buf[0] = size - i * read_size;
+ if (buf[0] > 0)
+ {
+ SetRWSize (chip, 1, buf[0]);
+ status = WriteIOControl (chip, 0x03, 0, 4, (SANE_Byte *) (buf));
+
+ status =
+ sanei_usb_read_bulk (chip->fd, lpdata + i * read_size,
+ (size_t *) buf);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Mustek_DMARead: read error\n");
+ return status;
+ }
+
+ usleep (20000);
+ }
+
+ DBG (DBG_ASIC, "Mustek_DMARead: Exit\n");
+ return STATUS_GOOD;
+}
+
+static STATUS
+Mustek_DMAWrite (PAsic chip, unsigned int size, SANE_Byte * lpdata)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned int buf[1];
+ unsigned int i;
+ unsigned int write_size;
+
+ DBG (DBG_ASIC, "Mustek_DMAWrite: Enter:size=%d\n", size);
+
+ status = Mustek_ClearFIFO (chip);
+ if (status != STATUS_GOOD)
+ return status;
+
+ buf[0] = write_size = 32 * 1024;
+ for (i = 0; i < size / (write_size); i++)
+ {
+ SetRWSize (chip, 0, buf[0]);
+ WriteIOControl (chip, 0x02, 0, 4, (SANE_Byte *) buf);
+
+ status =
+ sanei_usb_write_bulk (chip->fd, lpdata + i * write_size,
+ (size_t *) buf);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Mustek_DMAWrite: write error\n");
+ return status;
+ }
+ }
+
+
+ buf[0] = size - i * write_size;
+ if (buf[0] > 0)
+ {
+ SetRWSize (chip, 0, buf[0]);
+ WriteIOControl (chip, 0x02, 0, 4, (SANE_Byte *) buf);
+
+ status =
+ sanei_usb_write_bulk (chip->fd, lpdata + i * write_size,
+ (size_t *) buf);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Mustek_DMAWrite: write error\n");
+ return status;
+ }
+ }
+
+ Mustek_ClearFIFO (chip);
+
+ DBG (DBG_ASIC, "Mustek_DMAWrite: Exit\n");
+ return STATUS_GOOD;
+}
+
+
+static STATUS
+Mustek_SendData2Byte (PAsic chip, unsigned short reg, SANE_Byte data)
+{
+ static SANE_Bool isTransfer = FALSE;
+ static SANE_Byte BankBuf[4];
+ static SANE_Byte DataBuf[4];
+
+ if (reg <= 0xFF)
+ {
+ if (RegisterBankStatus != 0)
+ {
+ DBG (DBG_ASIC, "RegisterBankStatus=%d\n", RegisterBankStatus);
+ BankBuf[0] = ES01_5F_REGISTER_BANK_SELECT;
+ BankBuf[1] = SELECT_REGISTER_BANK0;
+ BankBuf[2] = ES01_5F_REGISTER_BANK_SELECT;
+ BankBuf[3] = SELECT_REGISTER_BANK0;
+ WriteIOControl (chip, 0xb0, 0, 4, BankBuf);
+
+ RegisterBankStatus = 0;
+ }
+ }
+ else if (reg <= 0x1FF)
+ {
+ if (RegisterBankStatus != 1)
+ {
+ DBG (DBG_ASIC, "RegisterBankStatus=%d\n", RegisterBankStatus);
+ BankBuf[0] = ES01_5F_REGISTER_BANK_SELECT;
+ BankBuf[1] = SELECT_REGISTER_BANK1;
+ BankBuf[2] = ES01_5F_REGISTER_BANK_SELECT;
+
+ BankBuf[3] = SELECT_REGISTER_BANK1;
+ WriteIOControl (chip, 0xb0, 0, 4, BankBuf);
+ RegisterBankStatus = 1;
+ }
+ }
+ else if (reg <= 0x2FF)
+ {
+ if (RegisterBankStatus != 2)
+ {
+ DBG (DBG_ASIC, "RegisterBankStatus=%d\n", RegisterBankStatus);
+ BankBuf[0] = ES01_5F_REGISTER_BANK_SELECT;
+ BankBuf[1] = SELECT_REGISTER_BANK2;
+ BankBuf[2] = ES01_5F_REGISTER_BANK_SELECT;
+ BankBuf[3] = SELECT_REGISTER_BANK2;
+ WriteIOControl (chip, 0xb0, 0, 4, BankBuf);
+ RegisterBankStatus = 2;
+ }
+ }
+
+ if (isTransfer == FALSE)
+ {
+ DataBuf[0] = LOBYTE (reg);
+ DataBuf[1] = data;
+ isTransfer = TRUE;
+ }
+ else
+ {
+ DataBuf[2] = LOBYTE (reg);
+ DataBuf[3] = data;
+ WriteIOControl (chip, 0xb0, 0, 4, DataBuf);
+ isTransfer = FALSE;
+ }
+
+ return STATUS_GOOD;
+}
+
+
+
+/* ---------------------- asic motor functions ----------------------------- */
+
+static STATUS
+LLFRamAccess (PAsic chip, LLF_RAMACCESS * RamAccess)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte a[2];
+
+ DBG (DBG_ASIC, "LLFRamAccess:Enter\n");
+
+ /*Set start address. Unit is a word. */
+ Mustek_SendData (chip, ES01_A0_HostStartAddr0_7,
+ LOBYTE (RamAccess->LoStartAddress));
+
+ if (RamAccess->IsOnChipGamma == ON_CHIP_FINAL_GAMMA)
+ { /* final gamma */
+ Mustek_SendData (chip, ES01_A1_HostStartAddr8_15,
+ HIBYTE (RamAccess->LoStartAddress));
+ Mustek_SendData (chip, ES01_A2_HostStartAddr16_21,
+ LOBYTE (RamAccess->HiStartAddress) | ACCESS_GAMMA_RAM);
+ }
+ else if (RamAccess->IsOnChipGamma == ON_CHIP_PRE_GAMMA)
+ { /* pre gamma */
+ Mustek_SendData (chip, ES01_A1_HostStartAddr8_15,
+ HIBYTE (RamAccess->
+ LoStartAddress) | ES01_ACCESS_PRE_GAMMA);
+ Mustek_SendData (chip, ES01_A2_HostStartAddr16_21,
+ LOBYTE (RamAccess->HiStartAddress) | ACCESS_GAMMA_RAM);
+ }
+ else
+ { /* dram */
+ Mustek_SendData (chip, ES01_A1_HostStartAddr8_15,
+ HIBYTE (RamAccess->LoStartAddress));
+ Mustek_SendData (chip, ES01_A2_HostStartAddr16_21,
+ LOBYTE (RamAccess->HiStartAddress) | ACCESS_DRAM);
+ }
+
+ /* set SDRAM delay time */
+ Mustek_SendData (chip, ES01_79_AFEMCLK_SDRAMCLK_DELAY_CONTROL,
+ SDRAMCLK_DELAY_12_ns);
+
+ /*Set end address. Unit is a word. */
+ Mustek_SendData (chip, ES01_A3_HostEndAddr0_7, 0xff);
+ Mustek_SendData (chip, ES01_A4_HostEndAddr8_15, 0xff);
+ Mustek_SendData (chip, ES01_A5_HostEndAddr16_21, 0xff);
+ Mustek_ClearFIFO (chip);
+
+ if (RamAccess->ReadWrite == WRITE_RAM)
+ { /*Write RAM */
+ Mustek_DMAWrite (chip, RamAccess->RwSize, RamAccess->BufferPtr); /* read-write size must be even */
+
+ /*steal read 2byte */
+ usleep (20000);
+ RamAccess->RwSize = 2;
+ RamAccess->BufferPtr = (SANE_Byte *) a;
+ RamAccess->ReadWrite = READ_RAM;
+ LLFRamAccess (chip, RamAccess);
+ DBG (DBG_ASIC, "end steal 2 byte!\n");
+ }
+ else
+ { /* Read RAM */
+ Mustek_DMARead (chip, RamAccess->RwSize, RamAccess->BufferPtr); /* read-write size must be even */
+ }
+
+ DBG (DBG_ASIC, "LLFRamAccess:Exit\n");
+ return status;
+}
+
+
+static STATUS
+LLFSetMotorCurrentAndPhase (PAsic chip,
+ LLF_MOTOR_CURRENT_AND_PHASE *
+ MotorCurrentAndPhase)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte MotorPhase;
+
+ DBG (DBG_ASIC, "LLFSetMotorCurrentAndPhase:Enter\n");
+
+ if (MotorCurrentAndPhase->MotorDriverIs3967 == 1)
+ {
+ MotorPhase = 0xFE;
+ }
+ else
+ {
+ MotorPhase = 0xFF;
+ }
+
+ DBG (DBG_ASIC, "MotorPhase=0x%x\n", MotorPhase);
+ Mustek_SendData (chip, ES02_50_MOTOR_CURRENT_CONTORL, 0x01);
+
+ if (MotorCurrentAndPhase->FillPhase == 0)
+ {
+ Mustek_SendData (chip, ES01_AB_PWM_CURRENT_CONTROL, 0x00);
+
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*2 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*3 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*4 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+ }
+ else
+ {
+ if (MotorCurrentAndPhase->MoveType == _4_TABLE_SPACE_FOR_FULL_STEP)
+ { /* Full Step */
+ Mustek_SendData (chip, ES01_AB_PWM_CURRENT_CONTROL, 0x00);
+
+ /*1 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*2 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*3 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*4 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+ }
+ else if (MotorCurrentAndPhase->MoveType ==
+ _8_TABLE_SPACE_FOR_1_DIV_2_STEP)
+ { /* Half Step */
+ Mustek_SendData (chip, ES01_AB_PWM_CURRENT_CONTROL, 0x01);
+
+ /*1 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x25 & MotorPhase);
+
+ /*2 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x07 & MotorPhase);
+
+ /*3 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x24 & MotorPhase);
+
+ /*4 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x30 & MotorPhase);
+
+ /*5 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x2c & MotorPhase);
+
+ /*6 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x0e & MotorPhase);
+
+ /*7 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x2d & MotorPhase);
+
+ /*8 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ MotorCurrentAndPhase->MotorCurrentTableA[0]);
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ MotorCurrentAndPhase->MotorCurrentTableB[0]);
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x39 & MotorPhase);
+ }
+ else if (MotorCurrentAndPhase->MoveType ==
+ _16_TABLE_SPACE_FOR_1_DIV_4_STEP)
+ { /* 1/4 step */
+ Mustek_SendData (chip, ES01_AB_PWM_CURRENT_CONTROL, 0x02);
+
+ /*1 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (0 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (0 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*2 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (1 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (1 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*3 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (2 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (2 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*4 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (3 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (3 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*5 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * cos (0 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * sin (0 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*6 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * cos (1 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * sin (1 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*7 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * cos (2 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * sin (2 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*8 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * cos (3 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * sin (3 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*9 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (0 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (0 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*10 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (1 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (1 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*11 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (2 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (2 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*12 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (3 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (3 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*13 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * cos (0 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * sin (0 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*14 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * cos (1 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * sin (1 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*15 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * cos (2 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * sin (2 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*16 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * cos (3 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * sin (3 *
+ 3.141592654
+ * 90 /
+ 4 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ }
+ else if (MotorCurrentAndPhase->MoveType ==
+ _32_TABLE_SPACE_FOR_1_DIV_8_STEP)
+ {
+ Mustek_SendData (chip, ES01_AB_PWM_CURRENT_CONTROL, 0x03);
+
+ /*1 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (0 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (0 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*2 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (1 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (1 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*3 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (2 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (2 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*4 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (3 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (3 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*5 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (4 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (4 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*6 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (5 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (5 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*7 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (6 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (6 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*8 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (7 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (7 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x00 & MotorPhase);
+
+ /*9 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (0 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (0 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*10 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (1 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (1 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*11 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (2 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (2 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*12 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (3 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (3 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*13 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (4 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (4 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*14 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (5 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (5 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*15 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (6 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (6 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*16 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (7 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (7 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x08 & MotorPhase);
+
+ /*17 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (0 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (0 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*18 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (1 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (1 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*19 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (2 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (2 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*20 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (3 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (3 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*21 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (4 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (4 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*22 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (5 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (5 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*23 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (6 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (6 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*24 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (7 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (7 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x09 & MotorPhase);
+
+ /*25 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (0 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (0 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*26 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (1 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (1 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*27 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (2 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (2 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*28 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (3 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (3 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*29 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (4 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (4 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*30 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (5 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (5 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*31 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (6 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (6 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ /*32 */
+ Mustek_SendData2Byte (chip, ES02_52_MOTOR_CURRENT_TABLE_A,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableA[0] * sin (7 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_53_MOTOR_CURRENT_TABLE_B,
+ (SANE_Byte) (MotorCurrentAndPhase->
+ MotorCurrentTableB[0] * cos (7 *
+ 3.141592654
+ * 90 /
+ 8 /
+ 180)));
+ Mustek_SendData2Byte (chip, ES02_51_MOTOR_PHASE_TABLE_1,
+ 0x01 & MotorPhase);
+
+ }
+ }
+
+ if (MotorCurrentAndPhase->FillPhase != 0)
+ {
+ Mustek_SendData (chip, ES02_50_MOTOR_CURRENT_CONTORL,
+ 0x00 | MotorCurrentAndPhase->MoveType);
+ }
+ else
+ {
+ Mustek_SendData (chip, ES02_50_MOTOR_CURRENT_CONTORL, 0x00);
+ }
+
+ DBG (DBG_ASIC, "LLFSetMotorCurrentAndPhase:Exit\n");
+ return status;
+}
+
+
+#if SANE_UNUSED
+static STATUS
+LLFStopMotorMove (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "LLFStopMotorMove:Enter\n");
+
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+
+ Asic_WaitUnitReady (chip);
+
+ DBG (DBG_ASIC, "LLFStopMotorMove:Exit\n");
+ return status;
+}
+#endif
+
+static STATUS
+LLFSetMotorTable (PAsic chip, LLF_SETMOTORTABLE * LLF_SetMotorTable)
+{
+ STATUS status = STATUS_GOOD;
+ LLF_RAMACCESS RamAccess;
+
+ DBG (DBG_ASIC, "LLFSetMotorTable:Enter\n");
+ if (LLF_SetMotorTable->MotorTablePtr != NULL)
+ {
+ RamAccess.ReadWrite = WRITE_RAM;
+ RamAccess.IsOnChipGamma = EXTERNAL_RAM;
+ RamAccess.DramDelayTime = SDRAMCLK_DELAY_12_ns;
+
+ RamAccess.LoStartAddress = 0;
+ RamAccess.LoStartAddress |= LLF_SetMotorTable->MotorTableAddress;
+ RamAccess.LoStartAddress <<= TABLE_OFFSET_BASE;
+ RamAccess.LoStartAddress |= 0x3000;
+
+ RamAccess.HiStartAddress = 0;
+ RamAccess.HiStartAddress |= LLF_SetMotorTable->MotorTableAddress;
+ RamAccess.HiStartAddress >>= (16 - TABLE_OFFSET_BASE);
+
+ RamAccess.RwSize = 512 * 2 * 8; /* BYTE */
+ RamAccess.BufferPtr = (SANE_Byte *) LLF_SetMotorTable->MotorTablePtr;
+
+ LLFRamAccess (chip, &RamAccess);
+
+ /* tell scan chip the motor table address, unit is 2^14 words */
+ Mustek_SendData (chip, ES01_9D_MotorTableAddrA14_A21,
+ LLF_SetMotorTable->MotorTableAddress);
+ }
+
+ DBG (DBG_ASIC, "LLFSetMotorTable:Exit\n");
+ return status;
+}
+
+static STATUS
+LLFMotorMove (PAsic chip, LLF_MOTORMOVE * LLF_MotorMove)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned int motor_steps;
+ SANE_Byte temp_motor_action;
+ SANE_Byte temp_status;
+
+ DBG (DBG_ASIC, "LLFMotorMove:Enter\n");
+
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+
+ status = Asic_WaitUnitReady (chip);
+
+ DBG (DBG_ASIC, "Set start/end pixel\n");
+
+ Mustek_SendData (chip, ES01_B8_ChannelRedExpStartPixelLSB, LOBYTE (100));
+ Mustek_SendData (chip, ES01_B9_ChannelRedExpStartPixelMSB, HIBYTE (100));
+ Mustek_SendData (chip, ES01_BA_ChannelRedExpEndPixelLSB, LOBYTE (101));
+ Mustek_SendData (chip, ES01_BB_ChannelRedExpEndPixelMSB, HIBYTE (101));
+
+ Mustek_SendData (chip, ES01_BC_ChannelGreenExpStartPixelLSB, LOBYTE (100));
+ Mustek_SendData (chip, ES01_BD_ChannelGreenExpStartPixelMSB, HIBYTE (100));
+ Mustek_SendData (chip, ES01_BE_ChannelGreenExpEndPixelLSB, LOBYTE (101));
+ Mustek_SendData (chip, ES01_BF_ChannelGreenExpEndPixelMSB, HIBYTE (101));
+
+ Mustek_SendData (chip, ES01_C0_ChannelBlueExpStartPixelLSB, LOBYTE (100));
+ Mustek_SendData (chip, ES01_C1_ChannelBlueExpStartPixelMSB, HIBYTE (100));
+ Mustek_SendData (chip, ES01_C2_ChannelBlueExpEndPixelLSB, LOBYTE (101));
+ Mustek_SendData (chip, ES01_C3_ChannelBlueExpEndPixelMSB, HIBYTE (101));
+
+ /*set motor accelerate steps MAX 511 steps */
+ Mustek_SendData (chip, ES01_E0_MotorAccStep0_7,
+ LOBYTE (LLF_MotorMove->AccStep));
+ Mustek_SendData (chip, ES01_E1_MotorAccStep8_8,
+ HIBYTE (LLF_MotorMove->AccStep));
+ DBG (DBG_ASIC, "AccStep=%d\n", LLF_MotorMove->AccStep);
+
+ Mustek_SendData (chip, ES01_E2_MotorStepOfMaxSpeed0_7,
+ LOBYTE (LLF_MotorMove->FixMoveSteps));
+ Mustek_SendData (chip, ES01_E3_MotorStepOfMaxSpeed8_15,
+ HIBYTE (LLF_MotorMove->FixMoveSteps));
+ Mustek_SendData (chip, ES01_E4_MotorStepOfMaxSpeed16_19, 0);
+ DBG (DBG_ASIC, "FixMoveSteps=%d\n", LLF_MotorMove->FixMoveSteps);
+
+ /*set motor decelerate steps MAX 255 steps */
+ Mustek_SendData (chip, ES01_E5_MotorDecStep, LLF_MotorMove->DecStep);
+ DBG (DBG_ASIC, "DecStep=%d\n", LLF_MotorMove->DecStep);
+
+ /*set motor uniform speed only for uniform speed
+ //only used for UNIFORM_MOTOR_AND_SCAN_SPEED_ENABLE
+ //If you use acc mode, this two reg are not used. */
+ Mustek_SendData (chip, ES01_FD_MotorFixedspeedLSB,
+ LOBYTE (LLF_MotorMove->FixMoveSpeed));
+ Mustek_SendData (chip, ES01_FE_MotorFixedspeedMSB,
+ HIBYTE (LLF_MotorMove->FixMoveSpeed));
+ DBG (DBG_ASIC, "FixMoveSpeed=%d\n", LLF_MotorMove->FixMoveSpeed);
+
+ /*Set motor type */
+ Mustek_SendData (chip, ES01_A6_MotorOption, LLF_MotorMove->MotorSelect |
+ LLF_MotorMove->HomeSensorSelect | LLF_MotorMove->
+ MotorMoveUnit);
+
+ /*Set motor speed unit, for all motor mode,
+ //inclue uniform, acc, motor speed of scan */
+ Mustek_SendData (chip, ES01_F6_MorotControl1,
+ LLF_MotorMove->MotorSpeedUnit | LLF_MotorMove->
+ MotorSyncUnit);
+
+ /* below is setting action register */
+ if (LLF_MotorMove->ActionType == ACTION_TYPE_BACKTOHOME)
+ {
+ DBG (DBG_ASIC, "ACTION_TYPE_BACKTOHOME\n");
+
+ temp_motor_action = MOTOR_BACK_HOME_AFTER_SCAN_ENABLE;
+ motor_steps = 30000 * 2;
+ }
+ else
+ {
+ DBG (DBG_ASIC, "Forward or Backward\n");
+ temp_motor_action = MOTOR_MOVE_TO_FIRST_LINE_ENABLE;
+ motor_steps = LLF_MotorMove->FixMoveSteps;
+
+ if (LLF_MotorMove->ActionType == ACTION_TYPE_BACKWARD)
+ {
+ DBG (DBG_ASIC, "ACTION_TYPE_BACKWARD\n");
+ temp_motor_action =
+ temp_motor_action | INVERT_MOTOR_DIRECTION_ENABLE;
+ }
+ }
+
+ if (LLF_MotorMove->ActionType == ACTION_TYPE_TEST_MODE)
+ {
+ DBG (DBG_ASIC, "ACTION_TYPE_TEST_MODE\n");
+ temp_motor_action = temp_motor_action |
+ MOTOR_MOVE_TO_FIRST_LINE_ENABLE |
+ MOTOR_BACK_HOME_AFTER_SCAN_ENABLE | MOTOR_TEST_LOOP_ENABLE;
+ }
+
+ Mustek_SendData (chip, ES01_94_PowerSaveControl,
+ 0x27 | LLF_MotorMove->Lamp0PwmFreq | LLF_MotorMove->
+ Lamp1PwmFreq);
+
+ /* fix speed move steps */
+ Mustek_SendData (chip, ES01_E2_MotorStepOfMaxSpeed0_7,
+ LOBYTE (motor_steps));
+ Mustek_SendData (chip, ES01_E3_MotorStepOfMaxSpeed8_15,
+ HIBYTE (motor_steps));
+ Mustek_SendData (chip, ES01_E4_MotorStepOfMaxSpeed16_19,
+ (SANE_Byte) ((motor_steps & 0x00ff0000) >> 16));
+ DBG (DBG_ASIC, "motor_steps=%d\n", motor_steps);
+ DBG (DBG_ASIC, "LOBYTE(motor_steps)=%d\n", LOBYTE (motor_steps));
+ DBG (DBG_ASIC, "HIBYTE(motor_steps)=%d\n", HIBYTE (motor_steps));
+ DBG (DBG_ASIC, "(SANE_Byte)((motor_steps & 0x00ff0000) >> 16)=%d\n",
+ (SANE_Byte) ((motor_steps & 0x00ff0000) >> 16));
+
+ if (LLF_MotorMove->ActionMode == ACTION_MODE_UNIFORM_SPEED_MOVE)
+ {
+ temp_motor_action =
+ temp_motor_action | UNIFORM_MOTOR_AND_SCAN_SPEED_ENABLE;
+ }
+
+ Mustek_SendData (chip, ES01_F3_ActionOption, SCAN_DISABLE |
+ SCAN_BACK_TRACKING_DISABLE | temp_motor_action);
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_ENABLE);
+
+ temp_status = 0;
+ if (LLF_MotorMove->WaitOrNoWait == 1)
+ {
+ if (LLF_MotorMove->ActionType == ACTION_TYPE_BACKTOHOME)
+ {
+ DBG (DBG_ASIC, "ACTION_TYPE_BACKTOHOME\n");
+ Asic_WaitCarriageHome (chip, FALSE);
+ }
+ else
+ {
+ Asic_WaitUnitReady (chip);
+ }
+ }
+
+ DBG (DBG_ASIC, "LLFMotorMove:Exit\n");
+ return status;
+}
+
+static STATUS
+SetMotorStepTable (PAsic chip, LLF_MOTORMOVE * MotorStepsTable, unsigned short wStartY,
+ unsigned int dwScanImageSteps, unsigned short wYResolution)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned short wAccSteps = 511;
+ unsigned short wForwardSteps = 20;
+ SANE_Byte bDecSteps = 255;
+ unsigned short wMotorSycnPixelNumber = 0;
+ unsigned short wScanAccSteps = 511;
+ SANE_Byte bScanDecSteps = 255;
+ unsigned short wFixScanSteps = 20;
+ unsigned short wScanBackTrackingSteps = 40;
+ unsigned short wScanRestartSteps = 40;
+ unsigned short wScanBackHomeExtSteps = 100;
+ unsigned int dwTotalMotorSteps;
+
+ DBG (DBG_ASIC, "SetMotorStepTable:Enter\n");
+
+ dwTotalMotorSteps = dwScanImageSteps;
+
+ switch (wYResolution)
+ {
+ case 2400:
+ case 1200:
+ wScanAccSteps = 100;
+ bScanDecSteps = 10;
+ wScanBackTrackingSteps = 10;
+ wScanRestartSteps = 10;
+ break;
+ case 600:
+ case 300:
+ wScanAccSteps = 300;
+ bScanDecSteps = 40;
+ break;
+ case 150:
+ wScanAccSteps = 300;
+ bScanDecSteps = 40;
+ break;
+ case 100:
+ case 75:
+ case 50:
+ wScanAccSteps = 300;
+ bScanDecSteps = 40;
+ break;
+ }
+
+ if (wStartY < (wAccSteps + wForwardSteps + bDecSteps + wScanAccSteps)) /*not including T0,T1 steps */
+ {
+ wAccSteps = 1;
+ bDecSteps = 1;
+ wFixScanSteps = (wStartY - wScanAccSteps) > 0 ?
+ (wStartY - wScanAccSteps) : 0;
+ wForwardSteps = 0;
+
+ chip->isMotorGoToFirstLine = MOTOR_MOVE_TO_FIRST_LINE_DISABLE;
+ }
+ else
+ {
+ wForwardSteps =
+ (wStartY - wAccSteps - (unsigned short) bDecSteps - wScanAccSteps -
+ wFixScanSteps) >
+ 0 ? (wStartY - wAccSteps - (unsigned short) bDecSteps - wScanAccSteps -
+ wFixScanSteps) : 0;
+
+ chip->isMotorGoToFirstLine = MOTOR_MOVE_TO_FIRST_LINE_ENABLE;
+ }
+
+ dwTotalMotorSteps += wAccSteps;
+ dwTotalMotorSteps += wForwardSteps;
+ dwTotalMotorSteps += bDecSteps;
+ dwTotalMotorSteps += wScanAccSteps;
+ dwTotalMotorSteps += wFixScanSteps;
+ dwTotalMotorSteps += bScanDecSteps;
+ dwTotalMotorSteps += 2;
+
+
+ MotorStepsTable->AccStep = wAccSteps;
+ MotorStepsTable->DecStep = bDecSteps;
+ MotorStepsTable->wForwardSteps = wForwardSteps;
+ MotorStepsTable->wScanAccSteps = wScanAccSteps;
+ MotorStepsTable->bScanDecSteps = bScanDecSteps;
+ MotorStepsTable->wFixScanSteps = wFixScanSteps;
+ MotorStepsTable->MotorSyncUnit = (SANE_Byte) wMotorSycnPixelNumber;
+ MotorStepsTable->wScanBackHomeExtSteps = wScanBackHomeExtSteps;
+ MotorStepsTable->wScanRestartSteps = wScanRestartSteps;
+ MotorStepsTable->wScanBackTrackingSteps = wScanBackTrackingSteps;
+
+ /*state 1 */
+ Mustek_SendData (chip, ES01_E0_MotorAccStep0_7, LOBYTE (wAccSteps));
+ Mustek_SendData (chip, ES01_E1_MotorAccStep8_8, HIBYTE (wAccSteps));
+ /*state 2 */
+ Mustek_SendData (chip, ES01_E2_MotorStepOfMaxSpeed0_7,
+ LOBYTE (wForwardSteps));
+ Mustek_SendData (chip, ES01_E3_MotorStepOfMaxSpeed8_15,
+ HIBYTE (wForwardSteps));
+ Mustek_SendData (chip, ES01_E4_MotorStepOfMaxSpeed16_19, 0);
+ /*state 3 */
+ Mustek_SendData (chip, ES01_E5_MotorDecStep, bDecSteps);
+ /*state 4 */
+ Mustek_SendData (chip, ES01_AE_MotorSyncPixelNumberM16LSB,
+ LOBYTE (wMotorSycnPixelNumber));
+ Mustek_SendData (chip, ES01_AF_MotorSyncPixelNumberM16MSB,
+ HIBYTE (wMotorSycnPixelNumber));
+ /*state 5 */
+ Mustek_SendData (chip, ES01_EC_ScanAccStep0_7, LOBYTE (wScanAccSteps));
+ Mustek_SendData (chip, ES01_ED_ScanAccStep8_8, HIBYTE (wScanAccSteps));
+ /*state 6 */
+ Mustek_SendData (chip, ES01_EE_FixScanStepLSB, LOBYTE (wFixScanSteps));
+ Mustek_SendData (chip, ES01_8A_FixScanStepMSB, HIBYTE (wFixScanSteps));
+ /*state 8 */
+ Mustek_SendData (chip, ES01_EF_ScanDecStep, bScanDecSteps);
+ /*state 10 */
+ Mustek_SendData (chip, ES01_E6_ScanBackTrackingStepLSB,
+ LOBYTE (wScanBackTrackingSteps));
+ Mustek_SendData (chip, ES01_E7_ScanBackTrackingStepMSB,
+ HIBYTE (wScanBackTrackingSteps));
+ /*state 15 */
+ Mustek_SendData (chip, ES01_E8_ScanRestartStepLSB,
+ LOBYTE (wScanRestartSteps));
+ Mustek_SendData (chip, ES01_E9_ScanRestartStepMSB,
+ HIBYTE (wScanRestartSteps));
+ /*state 19 */
+ Mustek_SendData (chip, ES01_EA_ScanBackHomeExtStepLSB,
+ LOBYTE (wScanBackHomeExtSteps));
+ Mustek_SendData (chip, ES01_EB_ScanBackHomeExtStepMSB,
+ HIBYTE (wScanBackHomeExtSteps));
+
+ /*total motor steps */
+ Mustek_SendData (chip, ES01_F0_ScanImageStep0_7,
+ LOBYTE (dwTotalMotorSteps));
+ Mustek_SendData (chip, ES01_F1_ScanImageStep8_15,
+ HIBYTE (dwTotalMotorSteps));
+ Mustek_SendData (chip, ES01_F2_ScanImageStep16_19,
+ (SANE_Byte) ((dwTotalMotorSteps & 0x00ff0000) >> 16));
+
+ DBG (DBG_ASIC, "SetMotorStepTable:Exit\n");
+ return status;
+}
+
+static STATUS
+CalculateMotorTable (LLF_CALCULATEMOTORTABLE * lpCalculateMotorTable,
+ unsigned short wYResolution)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned short i;
+ unsigned short wEndSpeed, wStartSpeed;
+ unsigned short wScanAccSteps;
+ SANE_Byte bScanDecSteps;
+ double PI = 3.1415926;
+ double x = PI / 2;
+ long double y;
+ unsigned short *lpMotorTable;
+
+ DBG (DBG_ASIC, "CalculateMotorTable:Enter\n");
+
+ wStartSpeed = lpCalculateMotorTable->StartSpeed;
+ wEndSpeed = lpCalculateMotorTable->EndSpeed;
+ wScanAccSteps = lpCalculateMotorTable->AccStepBeforeScan;
+ bScanDecSteps = lpCalculateMotorTable->DecStepAfterScan;
+ lpMotorTable = lpCalculateMotorTable->lpMotorTable;
+
+ /*Motor T0 & T6 Acc Table */
+ for (i = 0; i < 512; i++)
+ {
+ y = (6000 - 3500);
+ y *= (pow (0.09, (x * i) / 512) - pow (0.09, (x * 511) / 512));
+ y += 4500;
+ *((unsigned short *) lpMotorTable + i) = (unsigned short) y; /*T0 */
+ *((unsigned short *) lpMotorTable + i + 512 * 6) = (unsigned short) y; /*T6 */
+ }
+
+ /*Motor T1 & T7 Dec Table */
+ for (i = 0; i < 256; i++)
+ {
+ y = (6000 - 3500);
+ y *= pow (0.3, (x * i) / 256);
+ y = 6000 - y;
+ *((unsigned short *) lpMotorTable + i + 512) = (unsigned short) y; /*T1 */
+ *((unsigned short *) lpMotorTable + i + 512 * 7) = (unsigned short) y; /*T7 */
+ }
+
+ switch (wYResolution)
+ {
+ case 2400:
+ case 1200:
+ case 600:
+ case 300:
+ case 150:
+ case 100:
+ case 75:
+ case 50:
+ for (i = 0; i < wScanAccSteps; i++)
+ {
+ y = (wStartSpeed - wEndSpeed);
+ y *=
+ (pow (0.09, (x * i) / wScanAccSteps) -
+ pow (0.09, (x * (wScanAccSteps - 1)) / wScanAccSteps));
+ y += wEndSpeed;
+ *((unsigned short *) lpMotorTable + i + 512 * 2) = (unsigned short) y; /*T2 */
+ *((unsigned short *) lpMotorTable + i + 512 * 4) = (unsigned short) y; /*T4 */
+ }
+ for (i = wScanAccSteps; i < 512; i++)
+ {
+ *((unsigned short *) lpMotorTable + i + 512 * 2) = (unsigned short) wEndSpeed; /*T2 */
+ *((unsigned short *) lpMotorTable + i + 512 * 4) = (unsigned short) wEndSpeed; /*T4 */
+ }
+
+
+ for (i = 0; i < (unsigned short) bScanDecSteps; i++)
+ {
+ y = (wStartSpeed - wEndSpeed);
+ y *= pow (0.3, (x * i) / bScanDecSteps);
+ y = wStartSpeed - y;
+ *((unsigned short *) lpMotorTable + i + 512 * 3) = (unsigned short) (y); /*T3 */
+ *((unsigned short *) lpMotorTable + i + 512 * 5) = (unsigned short) (y); /*T5 */
+ }
+ for (i = bScanDecSteps; i < 256; i++)
+ {
+ *((unsigned short *) lpMotorTable + i + 512 * 3) = (unsigned short) wStartSpeed; /*T3 */
+ *((unsigned short *) lpMotorTable + i + 512 * 5) = (unsigned short) wStartSpeed; /*T5 */
+ }
+ break;
+ }
+
+ DBG (DBG_ASIC, "CalculateMotorTable:Exit\n");
+ return status;
+}
+
+static STATUS
+LLFCalculateMotorTable (LLF_CALCULATEMOTORTABLE * LLF_CalculateMotorTable)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned short i;
+ double PI = 3.1415926535;
+ double x;
+
+ DBG (DBG_ASIC, "LLF_CALCULATEMOTORTABLE:Enter\n");
+
+ x = PI / 2;
+
+ for (i = 0; i < 512; i++)
+ {
+ /* befor scan acc table */
+ *(LLF_CalculateMotorTable->lpMotorTable + i) =
+ (unsigned short) ((LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.09,
+ (x * i) / 512) +
+ LLF_CalculateMotorTable->EndSpeed);
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512 * 2) =
+ (unsigned short) ((LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.09,
+ (x * i) / 512) +
+ LLF_CalculateMotorTable->EndSpeed);
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512 * 4) =
+ (unsigned short) ((LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.09,
+ (x * i) / 512) +
+ LLF_CalculateMotorTable->EndSpeed);
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512 * 6) =
+ (unsigned short) ((LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.09,
+ (x * i) / 512) +
+ LLF_CalculateMotorTable->EndSpeed);
+ }
+
+ for (i = 0; i < 255; i++)
+ {
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512) =
+ (unsigned short) (LLF_CalculateMotorTable->StartSpeed -
+ (LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.3,
+ (x * i) / 256));
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512 * 3) =
+ (unsigned short) (LLF_CalculateMotorTable->StartSpeed -
+ (LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.3,
+ (x * i) / 256));
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512 * 5) =
+ (unsigned short) (LLF_CalculateMotorTable->StartSpeed -
+ (LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.3,
+ (x * i) / 256));
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512 * 7) =
+ (unsigned short) (LLF_CalculateMotorTable->StartSpeed -
+ (LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.3,
+ (x * i) / 256));
+ }
+
+ for (i = 0; i < 512; i++)
+ { /* back acc table */
+ *(LLF_CalculateMotorTable->lpMotorTable + i) =
+ (unsigned short) ((LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.09,
+ (x * i) / 512) +
+ LLF_CalculateMotorTable->EndSpeed);
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512 * 6) =
+ (unsigned short) ((LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * pow (0.09,
+ (x * i) / 512) +
+ LLF_CalculateMotorTable->EndSpeed);
+ }
+
+ if (LLF_CalculateMotorTable->AccStepBeforeScan == 0)
+ {
+ }
+ else
+ {
+ for (i = 0; i < LLF_CalculateMotorTable->AccStepBeforeScan; i++)
+ {
+ *(LLF_CalculateMotorTable->lpMotorTable + i + 512 * 2) =
+ (unsigned short) ((LLF_CalculateMotorTable->StartSpeed -
+ LLF_CalculateMotorTable->EndSpeed) * (pow (0.09,
+ (x * i) /
+ LLF_CalculateMotorTable->
+ AccStepBeforeScan)
+ - pow (0.09,
+ (x *
+ (LLF_CalculateMotorTable->
+ AccStepBeforeScan
+ -
+ 1)) /
+ LLF_CalculateMotorTable->
+ AccStepBeforeScan))
+ + LLF_CalculateMotorTable->EndSpeed);
+ }
+ }
+
+ DBG (DBG_ASIC, "LLF_CALCULATEMOTORTABLE:Exit\n");
+ return status;
+}
+
+
+static STATUS
+SetMotorCurrent (PAsic chip, unsigned short dwMotorSpeed,
+ LLF_MOTOR_CURRENT_AND_PHASE * CurrentPhase)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "SetMotorCurrent:Enter\n");
+
+ chip = chip;
+
+ if (dwMotorSpeed < 2000)
+ {
+ CurrentPhase->MotorCurrentTableA[0] = 255;
+ CurrentPhase->MotorCurrentTableB[0] = 255;
+ }
+ else if (dwMotorSpeed < 3500)
+ {
+ CurrentPhase->MotorCurrentTableA[0] = 200;
+ CurrentPhase->MotorCurrentTableB[0] = 200;
+ }
+ else if (dwMotorSpeed < 5000)
+ {
+ CurrentPhase->MotorCurrentTableA[0] = 160;
+ CurrentPhase->MotorCurrentTableB[0] = 160;
+ }
+ else if (dwMotorSpeed < 10000)
+ {
+ CurrentPhase->MotorCurrentTableA[0] = 70;
+ CurrentPhase->MotorCurrentTableB[0] = 70;
+ }
+ else if (dwMotorSpeed < 17000)
+ {
+ CurrentPhase->MotorCurrentTableA[0] = 60;
+ CurrentPhase->MotorCurrentTableB[0] = 60;
+ }
+ else if (dwMotorSpeed < 25000)
+ {
+ CurrentPhase->MotorCurrentTableA[0] = 50;
+ CurrentPhase->MotorCurrentTableB[0] = 50;
+ }
+ else
+ {
+ CurrentPhase->MotorCurrentTableA[0] = 50;
+ CurrentPhase->MotorCurrentTableB[0] = 50;
+ }
+
+ DBG (DBG_ASIC, "SetMotorCurrent:Exit\n");
+ return status;
+}
+
+
+static STATUS
+MotorBackHome (PAsic chip, SANE_Byte WaitOrNoWait)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned short BackHomeMotorTable[512 * 8];
+ LLF_CALCULATEMOTORTABLE CalMotorTable;
+ LLF_MOTOR_CURRENT_AND_PHASE CurrentPhase;
+ LLF_SETMOTORTABLE LLF_SetMotorTable;
+ LLF_MOTORMOVE MotorMove;
+
+ DBG (DBG_ASIC, "MotorBackHome:Enter\n");
+
+ CalMotorTable.StartSpeed = 5000;
+ CalMotorTable.EndSpeed = 1200;
+ CalMotorTable.AccStepBeforeScan = 511;
+ CalMotorTable.DecStepAfterScan = 255;
+ CalMotorTable.lpMotorTable = BackHomeMotorTable;
+ LLFCalculateMotorTable (&CalMotorTable);
+
+
+ CurrentPhase.MotorCurrentTableA[0] = 220;
+ CurrentPhase.MotorCurrentTableB[0] = 220;
+ CurrentPhase.MoveType = _4_TABLE_SPACE_FOR_FULL_STEP;
+ LLFSetMotorCurrentAndPhase (chip, &CurrentPhase);
+
+ LLF_SetMotorTable.MotorTableAddress = 0;
+ LLF_SetMotorTable.MotorTablePtr = BackHomeMotorTable;
+ LLFSetMotorTable (chip, &LLF_SetMotorTable);
+
+ MotorMove.MotorSelect = MOTOR_0_ENABLE | MOTOR_1_DISABLE;
+ MotorMove.MotorMoveUnit = ES03_TABLE_DEFINE;
+ MotorMove.MotorSpeedUnit = SPEED_UNIT_1_PIXEL_TIME;
+ MotorMove.MotorSyncUnit = MOTOR_SYNC_UNIT_1_PIXEL_TIME;
+ MotorMove.HomeSensorSelect = HOME_SENSOR_0_ENABLE;
+ MotorMove.ActionMode = ACTION_MODE_ACCDEC_MOVE;
+ MotorMove.ActionType = ACTION_TYPE_BACKTOHOME;
+
+ MotorMove.AccStep = 511;
+ MotorMove.DecStep = 255;
+ MotorMove.FixMoveSteps = 0;
+ MotorMove.FixMoveSpeed = 3000;
+ MotorMove.WaitOrNoWait = WaitOrNoWait;
+ LLFMotorMove (chip, &MotorMove);
+
+ DBG (DBG_ASIC, "MotorBackHome:Exit\n");
+ return status;
+}
+
+
+static STATUS
+LLFSetRamAddress (PAsic chip, unsigned int dwStartAddr, unsigned int dwEndAddr,
+ SANE_Byte byAccessTarget)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte * pStartAddr = (SANE_Byte *) & dwStartAddr;
+ SANE_Byte * pEndAddr = (SANE_Byte *) & dwEndAddr;
+
+ DBG (DBG_ASIC, "LLFSetRamAddress:Enter\n");
+
+ /*Set start address. */
+ Mustek_SendData (chip, ES01_A0_HostStartAddr0_7, *(pStartAddr));
+ Mustek_SendData (chip, ES01_A1_HostStartAddr8_15, *(pStartAddr + 1));
+ if (byAccessTarget == ACCESS_DRAM)
+ Mustek_SendData (chip, ES01_A2_HostStartAddr16_21,
+ *(pStartAddr + 2) | ACCESS_DRAM);
+ else
+ Mustek_SendData (chip, ES01_A2_HostStartAddr16_21,
+ *(pStartAddr + 2) | ACCESS_GAMMA_RAM);
+
+ /*Set end address. */
+ Mustek_SendData (chip, ES01_A3_HostEndAddr0_7, *(pEndAddr));
+ Mustek_SendData (chip, ES01_A4_HostEndAddr8_15, *(pEndAddr + 1));
+ Mustek_SendData (chip, ES01_A5_HostEndAddr16_21, *(pEndAddr + 2));
+
+ Mustek_ClearFIFO (chip);
+
+ DBG (DBG_ASIC, "LLFSetRamAddress:Exit\n");
+ return status;
+}
+
+
+
+/* ---------------------- medium level asic functions ---------------------- */
+
+static STATUS
+InitTiming (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "InitTiming:Enter\n");
+
+ chip->Timing.AFE_ADCCLK_Timing = 1010580480;
+ chip->Timing.AFE_ADCVS_Timing = 12582912;
+ chip->Timing.AFE_ADCRS_Timing = 3072;
+ chip->Timing.AFE_ChannelA_LatchPos = 3080;
+ chip->Timing.AFE_ChannelB_LatchPos = 3602;
+ chip->Timing.AFE_ChannelC_LatchPos = 5634;
+ chip->Timing.AFE_ChannelD_LatchPos = 1546;
+ chip->Timing.AFE_Secondary_FF_LatchPos = 12;
+
+ /* Sensor */
+ chip->Timing.CCD_DummyCycleTiming = 0;
+ chip->Timing.PHTG_PluseWidth = 12;
+ chip->Timing.PHTG_WaitWidth = 1;
+ chip->Timing.PHTG_TimingAdj = 1;
+ chip->Timing.PHTG_TimingSetup = 0;
+ chip->Timing.ChannelR_StartPixel = 100;
+ chip->Timing.ChannelR_EndPixel = 200;
+ chip->Timing.ChannelG_StartPixel = 100;
+ chip->Timing.ChannelG_EndPixel = 200;
+ chip->Timing.ChannelB_StartPixel = 100;
+ chip->Timing.ChannelB_EndPixel = 200;
+
+ /*1200dpi Timing */
+ chip->Timing.CCD_PH2_Timing_1200 = 1048320;
+ chip->Timing.CCD_PHRS_Timing_1200 = 983040;
+ chip->Timing.CCD_PHCP_Timing_1200 = 61440;
+ chip->Timing.CCD_PH1_Timing_1200 = 4293918720u;
+ chip->Timing.DE_CCD_SETUP_REGISTER_1200 = 32;
+ chip->Timing.wCCDPixelNumber_1200 = 11250;
+
+ /*600dpi Timing */
+ chip->Timing.CCD_PH2_Timing_600 = 1048320;
+ chip->Timing.CCD_PHRS_Timing_600 = 983040;
+ chip->Timing.CCD_PHCP_Timing_600 = 61440;
+ chip->Timing.CCD_PH1_Timing_600 = 4293918720u;
+ chip->Timing.DE_CCD_SETUP_REGISTER_600 = 0;
+ chip->Timing.wCCDPixelNumber_600 = 7500;
+
+ DBG (DBG_ASIC, "InitTiming:Exit\n");
+ return status;
+}
+
+static STATUS
+OpenScanChip (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte x[4];
+
+ DBG (DBG_ASIC, "OpenScanChip:Enter\n");
+
+ x[0] = 0x64;
+ x[1] = 0x64;
+ x[2] = 0x64;
+ x[3] = 0x64;
+ status = WriteIOControl (chip, 0x90, 0, 4, x);
+ if (status != STATUS_GOOD)
+ return status;
+
+ x[0] = 0x65;
+ x[1] = 0x65;
+ x[2] = 0x65;
+ x[3] = 0x65;
+ status = WriteIOControl (chip, 0x90, 0, 4, x);
+ if (status != STATUS_GOOD)
+ return status;
+
+ x[0] = 0x44;
+ x[1] = 0x44;
+ x[2] = 0x44;
+ x[3] = 0x44;
+ status = WriteIOControl (chip, 0x90, 0, 4, x);
+ if (status != STATUS_GOOD)
+ return status;
+
+ x[0] = 0x45;
+ x[1] = 0x45;
+ x[2] = 0x45;
+ x[3] = 0x45;
+ status = WriteIOControl (chip, 0x90, 0, 4, x);
+
+ DBG (DBG_ASIC, "OpenScanChip: Exit\n");
+ return status;
+}
+
+
+static STATUS
+CloseScanChip (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte x[4];
+
+ DBG (DBG_ASIC, "CloseScanChip:Enter\n");
+
+ x[0] = 0x64;
+ x[1] = 0x64;
+ x[2] = 0x64;
+ x[3] = 0x64;
+ status = WriteIOControl (chip, 0x90, 0, 4, x);
+ if (status != STATUS_GOOD)
+ return status;
+
+ x[0] = 0x65;
+ x[1] = 0x65;
+ x[2] = 0x65;
+ x[3] = 0x65;
+ status = WriteIOControl (chip, 0x90, 0, 4, x);
+ if (status != STATUS_GOOD)
+ return status;
+
+ x[0] = 0x16;
+ x[1] = 0x16;
+ x[2] = 0x16;
+ x[3] = 0x16;
+ status = WriteIOControl (chip, 0x90, 0, 4, x);
+ if (status != STATUS_GOOD)
+ return status;
+
+ x[0] = 0x17;
+ x[1] = 0x17;
+ x[2] = 0x17;
+ x[3] = 0x17;
+ status = WriteIOControl (chip, 0x90, 0, 4, x);
+
+ DBG (DBG_ASIC, "CloseScanChip: Exit\n");
+ return status;
+}
+
+
+static STATUS
+SafeInitialChip (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+
+ DBG (DBG_ASIC, "SafeInitialChip:Enter\n");
+
+ Mustek_SendData (chip, ES01_F3_ActionOption, 0);
+ Mustek_SendData (chip, ES01_86_DisableAllClockWhenIdle,
+ CLOSE_ALL_CLOCK_DISABLE);
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+
+ status = Asic_WaitUnitReady (chip);
+
+ DBG (DBG_ASIC, "isFirstOpenChip=%d\n", chip->isFirstOpenChip);
+ if (chip->isFirstOpenChip)
+ {
+ DBG (DBG_ASIC, "isFirstOpenChip=%d\n", chip->isFirstOpenChip);
+ status = DRAM_Test (chip);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ASIC, "DRAM_Test: Error\n");
+ return status;
+ }
+ chip->isFirstOpenChip = FALSE;
+ }
+
+ DBG (DBG_ASIC, "SafeInitialChip: exit\n");
+ return status;
+}
+
+
+static STATUS
+DRAM_Test (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned char *temps;
+ unsigned int i;
+
+ DBG (DBG_ASIC, "DRAM_Test:Enter\n");
+
+ temps = (unsigned char *) malloc (64);
+
+ for (i = 0; i < 64; i++)
+ {
+ *(temps + i) = i;
+ }
+
+ /*set start address */
+ status = Mustek_SendData (chip, ES01_A0_HostStartAddr0_7, 0x00);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status = Mustek_SendData (chip, ES01_A1_HostStartAddr8_15, 0x00);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status =
+ Mustek_SendData (chip, ES01_A2_HostStartAddr16_21, 0x00 | ACCESS_DRAM);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ Mustek_SendData (chip, ES01_79_AFEMCLK_SDRAMCLK_DELAY_CONTROL,
+ SDRAMCLK_DELAY_12_ns);
+ status = Mustek_SendData (chip, ES01_A3_HostEndAddr0_7, 0xff);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status = Mustek_SendData (chip, ES01_A4_HostEndAddr8_15, 0xff);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status = Mustek_SendData (chip, ES01_A5_HostEndAddr16_21, 0xff);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status = Mustek_DMAWrite (chip, 64, (SANE_Byte *) (temps));
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ASIC, "Mustek_DMAWrite error\n");
+ free (temps);
+ return status;
+ }
+
+ status = Mustek_SendData (chip, ES01_A0_HostStartAddr0_7, 0x00);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status = Mustek_SendData (chip, ES01_A1_HostStartAddr8_15, 0x00);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status =
+ Mustek_SendData (chip, ES01_A2_HostStartAddr16_21, 0x00 | ACCESS_DRAM);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ /*set end address */
+ status = Mustek_SendData (chip, ES01_A3_HostEndAddr0_7, 0xff);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status = Mustek_SendData (chip, ES01_A4_HostEndAddr8_15, 0xff);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ status = Mustek_SendData (chip, ES01_A5_HostEndAddr16_21, 0xff);
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ memset (temps, 0, 64);
+
+ status = Mustek_DMARead (chip, 64, (SANE_Byte *) (temps));
+ if (status != STATUS_GOOD)
+ {
+ free (temps);
+ return status;
+ }
+
+ for (i = 0; i < 60; i += 10)
+ {
+ DBG (DBG_ASIC, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
+ *(temps + i), *(temps + i + 1), *(temps + i + 2), *(temps + i + 3),
+ *(temps + i + 4), *(temps + i + 5), *(temps + i + 6),
+ *(temps + i + 7), *(temps + i + 8), *(temps + i + 9));
+ }
+
+ for (i = 0; i < 64; i++)
+ {
+ if (*(temps + i) != i)
+ {
+ DBG (DBG_ERR, "DRAM Test error...(No.=%d)\n", i + 1);
+ return STATUS_IO_ERROR;
+ }
+ }
+
+ free (temps);
+
+ DBG (DBG_ASIC, "DRAM_Text: Exit\n");
+ return status;
+}
+
+#if SANE_UNUSED
+static STATUS
+SetPowerSave (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "SetPowerSave:Enter\n");
+
+ if (chip->firmwarestate < FS_OPENED)
+ OpenScanChip (chip);
+
+ if (chip->firmwarestate > FS_OPENED)
+ Asic_ScanStop (chip);
+
+ Mustek_SendData (chip, ES01_94_PowerSaveControl, 0x10);
+
+ chip->firmwarestate = FS_OPENED;
+ DBG (DBG_ASIC, "SetPowerSave:Exit\n");
+ return status;
+}
+#endif
+
+static STATUS
+SetLineTimeAndExposure (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "SetLineTimeAndExposure:Enter\n");
+
+ if (chip->firmwarestate < FS_OPENED)
+ OpenScanChip (chip);
+
+ Mustek_SendData (chip, ES01_C4_MultiTGTimesRed, 0);
+ Mustek_SendData (chip, ES01_C5_MultiTGTimesGreen, 0);
+ Mustek_SendData (chip, ES01_C6_MultiTGTimesBlue, 0);
+
+ Mustek_SendData (chip, ES01_C7_MultiTGDummyPixelNumberLSB, 0);
+ Mustek_SendData (chip, ES01_C8_MultiTGDummyPixelNumberMSB, 0);
+
+ Mustek_SendData (chip, ES01_C9_CCDDummyPixelNumberLSB, 0);
+ Mustek_SendData (chip, ES01_CA_CCDDummyPixelNumberMSB, 0);
+
+ Mustek_SendData (chip, ES01_CB_CCDDummyCycleNumber, 0);
+
+
+ chip->firmwarestate = FS_OPENED;
+
+ DBG (DBG_ASIC, "SetLineTimeAndExposure:Exit\n");
+ return status;
+}
+
+
+
+
+
+static STATUS
+CCDTiming (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned int dwPH1, dwPH2, dwPHRS, dwPHCP;
+
+ DBG (DBG_ASIC, "CCDTiming:Enter\n");
+ DBG (DBG_ASIC, "Dpi=%d\n", chip->Scan.Dpi);
+
+ if (chip->firmwarestate < FS_OPENED)
+ OpenScanChip (chip);
+
+ Mustek_SendData (chip, ES01_82_AFE_ADCCLK_TIMING_ADJ_BYTE0,
+ (SANE_Byte) (chip->Timing.AFE_ADCCLK_Timing));
+ Mustek_SendData (chip, ES01_83_AFE_ADCCLK_TIMING_ADJ_BYTE1,
+ (SANE_Byte) (chip->Timing.AFE_ADCCLK_Timing >> 8));
+ Mustek_SendData (chip, ES01_84_AFE_ADCCLK_TIMING_ADJ_BYTE2,
+ (SANE_Byte) (chip->Timing.AFE_ADCCLK_Timing >> 16));
+ Mustek_SendData (chip, ES01_85_AFE_ADCCLK_TIMING_ADJ_BYTE3,
+ (SANE_Byte) (chip->Timing.AFE_ADCCLK_Timing >> 24));
+
+ Mustek_SendData (chip, ES01_1F0_AFERS_TIMING_ADJ_B0,
+ (SANE_Byte) (chip->Timing.AFE_ADCRS_Timing));
+ Mustek_SendData (chip, ES01_1F1_AFERS_TIMING_ADJ_B1,
+ (SANE_Byte) (chip->Timing.AFE_ADCRS_Timing >> 8));
+ Mustek_SendData (chip, ES01_1F2_AFERS_TIMING_ADJ_B2,
+ (SANE_Byte) (chip->Timing.AFE_ADCRS_Timing >> 16));
+ Mustek_SendData (chip, ES01_1F3_AFERS_TIMING_ADJ_B3,
+ (SANE_Byte) (chip->Timing.AFE_ADCRS_Timing >> 24));
+
+ Mustek_SendData (chip, ES01_1EC_AFEVS_TIMING_ADJ_B0,
+ (SANE_Byte) (chip->Timing.AFE_ADCVS_Timing));
+ Mustek_SendData (chip, ES01_1ED_AFEVS_TIMING_ADJ_B1,
+ (SANE_Byte) (chip->Timing.AFE_ADCVS_Timing >> 8));
+ Mustek_SendData (chip, ES01_1EE_AFEVS_TIMING_ADJ_B2,
+ (SANE_Byte) (chip->Timing.AFE_ADCVS_Timing >> 16));
+ Mustek_SendData (chip, ES01_1EF_AFEVS_TIMING_ADJ_B3,
+ (SANE_Byte) (chip->Timing.AFE_ADCVS_Timing >> 24));
+
+ Mustek_SendData (chip, ES01_160_CHANNEL_A_LATCH_POSITION_HB,
+ HIBYTE (chip->Timing.AFE_ChannelA_LatchPos));
+ Mustek_SendData (chip, ES01_161_CHANNEL_A_LATCH_POSITION_LB,
+ LOBYTE (chip->Timing.AFE_ChannelA_LatchPos));
+
+ Mustek_SendData (chip, ES01_162_CHANNEL_B_LATCH_POSITION_HB,
+ HIBYTE (chip->Timing.AFE_ChannelB_LatchPos));
+ Mustek_SendData (chip, ES01_163_CHANNEL_B_LATCH_POSITION_LB,
+ LOBYTE (chip->Timing.AFE_ChannelB_LatchPos));
+
+ Mustek_SendData (chip, ES01_164_CHANNEL_C_LATCH_POSITION_HB,
+ HIBYTE (chip->Timing.AFE_ChannelC_LatchPos));
+ Mustek_SendData (chip, ES01_165_CHANNEL_C_LATCH_POSITION_LB,
+ LOBYTE (chip->Timing.AFE_ChannelC_LatchPos));
+
+ Mustek_SendData (chip, ES01_166_CHANNEL_D_LATCH_POSITION_HB,
+ HIBYTE (chip->Timing.AFE_ChannelD_LatchPos));
+ Mustek_SendData (chip, ES01_167_CHANNEL_D_LATCH_POSITION_LB,
+ LOBYTE (chip->Timing.AFE_ChannelD_LatchPos));
+
+ Mustek_SendData (chip, ES01_168_SECONDARY_FF_LATCH_POSITION,
+ chip->Timing.AFE_Secondary_FF_LatchPos);
+
+ Mustek_SendData (chip, ES01_1D0_DUMMY_CYCLE_TIMING_B0,
+ (SANE_Byte) (chip->Timing.CCD_DummyCycleTiming));
+ Mustek_SendData (chip, ES01_1D1_DUMMY_CYCLE_TIMING_B1,
+ (SANE_Byte) (chip->Timing.CCD_DummyCycleTiming >> 8));
+ Mustek_SendData (chip, ES01_1D2_DUMMY_CYCLE_TIMING_B2,
+ (SANE_Byte) (chip->Timing.CCD_DummyCycleTiming >> 16));
+ Mustek_SendData (chip, ES01_1D3_DUMMY_CYCLE_TIMING_B3,
+ (SANE_Byte) (chip->Timing.CCD_DummyCycleTiming >> 24));
+
+ if (chip->Scan.Dpi >= 1200)
+ {
+ dwPH1 = chip->Timing.CCD_PH1_Timing_1200;
+ dwPH2 = chip->Timing.CCD_PH2_Timing_1200;
+ dwPHRS = chip->Timing.CCD_PHRS_Timing_1200;
+ dwPHCP = chip->Timing.CCD_PHCP_Timing_1200;
+ }
+ else
+ {
+ dwPH1 = chip->Timing.CCD_PH1_Timing_600;
+ dwPH2 = chip->Timing.CCD_PH2_Timing_600;
+ dwPHRS = chip->Timing.CCD_PHRS_Timing_600;
+ dwPHCP = chip->Timing.CCD_PHCP_Timing_600;
+ }
+
+ Mustek_SendData (chip, ES01_1D4_PH1_TIMING_ADJ_B0, (SANE_Byte) (dwPH1));
+ Mustek_SendData (chip, ES01_1D5_PH1_TIMING_ADJ_B1, (SANE_Byte) (dwPH1 >> 8));
+ Mustek_SendData (chip, ES01_1D6_PH1_TIMING_ADJ_B2, (SANE_Byte) (dwPH1 >> 16));
+ Mustek_SendData (chip, ES01_1D7_PH1_TIMING_ADJ_B3, (SANE_Byte) (dwPH1 >> 24));
+
+ /* set ccd ph1 ph2 rs cp */
+ Mustek_SendData (chip, ES01_D0_PH1_0, 0);
+ Mustek_SendData (chip, ES01_D1_PH2_0, 4);
+ Mustek_SendData (chip, ES01_D4_PHRS_0, 0);
+ Mustek_SendData (chip, ES01_D5_PHCP_0, 0);
+
+ Mustek_SendData (chip, ES01_1D8_PH2_TIMING_ADJ_B0, (SANE_Byte) (dwPH2));
+ Mustek_SendData (chip, ES01_1D9_PH2_TIMING_ADJ_B1, (SANE_Byte) (dwPH2 >> 8));
+ Mustek_SendData (chip, ES01_1DA_PH2_TIMING_ADJ_B2, (SANE_Byte) (dwPH2 >> 16));
+ Mustek_SendData (chip, ES01_1DB_PH2_TIMING_ADJ_B3, (SANE_Byte) (dwPH2 >> 24));
+
+ Mustek_SendData (chip, ES01_1E4_PHRS_TIMING_ADJ_B0, (SANE_Byte) (dwPHRS));
+ Mustek_SendData (chip, ES01_1E5_PHRS_TIMING_ADJ_B1, (SANE_Byte) (dwPHRS >> 8));
+ Mustek_SendData (chip, ES01_1E6_PHRS_TIMING_ADJ_B2, (SANE_Byte) (dwPHRS >> 16));
+ Mustek_SendData (chip, ES01_1E7_PHRS_TIMING_ADJ_B3, (SANE_Byte) (dwPHRS >> 24));
+
+ Mustek_SendData (chip, ES01_1E8_PHCP_TIMING_ADJ_B0, (SANE_Byte) (dwPHCP));
+ Mustek_SendData (chip, ES01_1E9_PHCP_TIMING_ADJ_B1, (SANE_Byte) (dwPHCP >> 8));
+ Mustek_SendData (chip, ES01_1EA_PHCP_TIMING_ADJ_B2, (SANE_Byte) (dwPHCP >> 16));
+ Mustek_SendData (chip, ES01_1EB_PHCP_TIMING_ADJ_B3, (SANE_Byte) (dwPHCP >> 24));
+
+ chip->firmwarestate = FS_OPENED;
+ DBG (DBG_ASIC, "CCDTiming:Exit\n");
+ return status;
+}
+
+static STATUS
+IsCarriageHome (PAsic chip, SANE_Bool * LampHome, SANE_Bool * TAHome)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte temp;
+
+ DBG (DBG_ASIC, "IsCarriageHome:Enter\n");
+
+ status = GetChipStatus (chip, 0, &temp);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ASIC, "IsCarriageHome:Error!\n");
+ return status;
+ }
+
+ if ((temp & SENSOR0_DETECTED) == SENSOR0_DETECTED)
+ *LampHome = TRUE;
+ else
+ {
+ *LampHome = FALSE;
+ }
+
+ *TAHome = TRUE;
+
+ DBG (DBG_ASIC, "LampHome=%d\n", *LampHome);
+
+ DBG (DBG_ASIC, "IsCarriageHome:Exit\n");
+ return status;
+}
+
+
+static STATUS
+GetChipStatus (PAsic chip, SANE_Byte Selector, SANE_Byte * ChipStatus)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "GetChipStatus:Enter\n");
+
+ status = Mustek_SendData (chip, ES01_8B_Status, Selector);
+ if (status != STATUS_GOOD)
+ return status;
+
+ status = Mustek_WriteAddressLineForRegister (chip, ES01_8B_Status);
+ if (status != STATUS_GOOD)
+ return status;
+
+ *ChipStatus = ES01_8B_Status;
+ status = Mustek_ReceiveData (chip, ChipStatus);
+ if (status != STATUS_GOOD)
+ return status;
+
+ DBG (DBG_ASIC, "GetChipStatus:Exit\n");
+ return status;
+}
+
+static STATUS
+SetAFEGainOffset (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ int i = 0;
+
+ DBG (DBG_ASIC, "SetAFEGainOffset:Enter\n");
+
+ if (chip->AD.DirectionR)
+ { /* Negative */
+ Mustek_SendData (chip, ES01_60_AFE_AUTO_GAIN_OFFSET_RED_LB,
+ (chip->AD.GainR << 1) | 0x01);
+ Mustek_SendData (chip, ES01_61_AFE_AUTO_GAIN_OFFSET_RED_HB,
+ chip->AD.OffsetR);
+ }
+ else
+ { /* Postive */
+ Mustek_SendData (chip, ES01_60_AFE_AUTO_GAIN_OFFSET_RED_LB,
+ (chip->AD.GainR << 1));
+ Mustek_SendData (chip, ES01_61_AFE_AUTO_GAIN_OFFSET_RED_HB,
+ chip->AD.OffsetR);
+ }
+
+ if (chip->AD.DirectionG)
+ {
+ Mustek_SendData (chip, ES01_62_AFE_AUTO_GAIN_OFFSET_GREEN_LB,
+ (chip->AD.GainG << 1) | 0x01);
+ Mustek_SendData (chip, ES01_63_AFE_AUTO_GAIN_OFFSET_GREEN_HB,
+ chip->AD.OffsetG);
+ }
+ else
+ {
+ Mustek_SendData (chip, ES01_62_AFE_AUTO_GAIN_OFFSET_GREEN_LB,
+ (chip->AD.GainG << 1));
+
+ Mustek_SendData (chip, ES01_63_AFE_AUTO_GAIN_OFFSET_GREEN_HB,
+ chip->AD.OffsetG);
+ }
+
+ if (chip->AD.DirectionB)
+ {
+ Mustek_SendData (chip, ES01_64_AFE_AUTO_GAIN_OFFSET_BLUE_LB,
+ (chip->AD.GainB << 1) | 0x01);
+ Mustek_SendData (chip, ES01_65_AFE_AUTO_GAIN_OFFSET_BLUE_HB,
+ chip->AD.OffsetB);
+ }
+ else
+ {
+ Mustek_SendData (chip, ES01_64_AFE_AUTO_GAIN_OFFSET_BLUE_LB,
+ (chip->AD.GainB << 1));
+ Mustek_SendData (chip, ES01_65_AFE_AUTO_GAIN_OFFSET_BLUE_HB,
+ chip->AD.OffsetB);
+ }
+
+
+ Mustek_SendData (chip, ES01_2A0_AFE_GAIN_OFFSET_CONTROL, 0x01);
+
+ for (i = 0; i < 4; i++)
+ {
+
+ if (chip->AD.DirectionR == 0)
+ {
+ Mustek_SendData (chip, ES01_2A1_AFE_AUTO_CONFIG_GAIN,
+ (SANE_Byte) (chip->AD.GainR << 1));
+ Mustek_SendData (chip, ES01_2A2_AFE_AUTO_CONFIG_OFFSET,
+ (SANE_Byte) (chip->AD.OffsetR));
+ }
+ else
+ {
+ Mustek_SendData (chip, ES01_2A1_AFE_AUTO_CONFIG_GAIN,
+ (SANE_Byte) (chip->AD.GainR << 1) | 0x01);
+ Mustek_SendData (chip, ES01_2A2_AFE_AUTO_CONFIG_OFFSET,
+ (SANE_Byte) (chip->AD.OffsetR));
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ if (chip->AD.DirectionG == 0)
+ {
+ Mustek_SendData (chip, ES01_2A1_AFE_AUTO_CONFIG_GAIN,
+ (SANE_Byte) (chip->AD.GainG << 1));
+ Mustek_SendData (chip, ES01_2A2_AFE_AUTO_CONFIG_OFFSET,
+ (SANE_Byte) (chip->AD.OffsetG));
+ }
+ else
+ {
+ Mustek_SendData (chip, ES01_2A1_AFE_AUTO_CONFIG_GAIN,
+ (SANE_Byte) (chip->AD.GainG << 1) | 0x01);
+ Mustek_SendData (chip, ES01_2A2_AFE_AUTO_CONFIG_OFFSET,
+ (SANE_Byte) (chip->AD.OffsetG));
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ if (chip->AD.DirectionB == 0)
+ {
+ Mustek_SendData (chip, ES01_2A1_AFE_AUTO_CONFIG_GAIN,
+ (SANE_Byte) (chip->AD.GainB << 1));
+ Mustek_SendData (chip, ES01_2A2_AFE_AUTO_CONFIG_OFFSET,
+ (SANE_Byte) (chip->AD.OffsetB));
+ }
+ else
+ {
+ Mustek_SendData (chip, ES01_2A1_AFE_AUTO_CONFIG_GAIN,
+ (SANE_Byte) (chip->AD.GainB << 1) | 0x01);
+ Mustek_SendData (chip, ES01_2A2_AFE_AUTO_CONFIG_OFFSET,
+ (SANE_Byte) (chip->AD.OffsetB));
+ }
+ }
+
+ for (i = 0; i < 36; i++)
+ {
+ Mustek_SendData (chip, ES01_2A1_AFE_AUTO_CONFIG_GAIN, 0);
+ Mustek_SendData (chip, ES01_2A2_AFE_AUTO_CONFIG_OFFSET, 0);
+ }
+
+ Mustek_SendData (chip, ES01_2A0_AFE_GAIN_OFFSET_CONTROL, 0x00);
+
+ /* Set to AFE */
+ Mustek_SendData (chip, ES01_04_ADAFEPGACH1, chip->AD.GainR);
+ Mustek_SendData (chip, ES01_06_ADAFEPGACH2, chip->AD.GainG);
+ Mustek_SendData (chip, ES01_08_ADAFEPGACH3, chip->AD.GainB);
+
+ if (chip->AD.DirectionR)
+ Mustek_SendData (chip, ES01_0B_AD9826OffsetRedN, chip->AD.OffsetR);
+ else
+ Mustek_SendData (chip, ES01_0A_AD9826OffsetRedP, chip->AD.OffsetR);
+
+ if (chip->AD.DirectionG)
+ Mustek_SendData (chip, ES01_0D_AD9826OffsetGreenN, chip->AD.OffsetG);
+ else
+ Mustek_SendData (chip, ES01_0C_AD9826OffsetGreenP, chip->AD.OffsetG);
+
+ if (chip->AD.DirectionB)
+ Mustek_SendData (chip, ES01_0F_AD9826OffsetBlueN, chip->AD.OffsetB);
+ else
+ Mustek_SendData (chip, ES01_0E_AD9826OffsetBlueP, chip->AD.OffsetB);
+
+
+ LLFSetRamAddress (chip, 0x0, PackAreaStartAddress - (512 * 8 - 1),
+ ACCESS_DRAM);
+
+ Mustek_SendData (chip, ES01_F3_ActionOption,
+ MOTOR_MOVE_TO_FIRST_LINE_DISABLE |
+ MOTOR_BACK_HOME_AFTER_SCAN_DISABLE |
+ SCAN_ENABLE |
+ SCAN_BACK_TRACKING_DISABLE |
+ INVERT_MOTOR_DIRECTION_DISABLE |
+ UNIFORM_MOTOR_AND_SCAN_SPEED_ENABLE |
+ ES01_STATIC_SCAN_DISABLE | MOTOR_TEST_LOOP_DISABLE);
+
+ Mustek_SendData (chip, ES01_9A_AFEControl,
+ AD9826_AFE | AUTO_CHANGE_AFE_GAIN_OFFSET_DISABLE);
+
+ Mustek_SendData (chip, ES01_00_ADAFEConfiguration, 0x70);
+ Mustek_SendData (chip, ES01_02_ADAFEMuxConfig, 0x80);
+
+ DBG (DBG_ASIC, "SetAFEGainOffset:Exit\n");
+ return status;
+}
+
+static STATUS
+SetLEDTime (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "SetLEDTime:Enter\n");
+
+ Mustek_SendData (chip, ES01_B8_ChannelRedExpStartPixelLSB,
+ LOBYTE (chip->Timing.ChannelR_StartPixel));
+ Mustek_SendData (chip, ES01_B9_ChannelRedExpStartPixelMSB,
+ HIBYTE (chip->Timing.ChannelR_StartPixel));
+ Mustek_SendData (chip, ES01_BA_ChannelRedExpEndPixelLSB,
+ LOBYTE (chip->Timing.ChannelR_EndPixel));
+ Mustek_SendData (chip, ES01_BB_ChannelRedExpEndPixelMSB,
+ HIBYTE (chip->Timing.ChannelR_EndPixel));
+
+ Mustek_SendData (chip, ES01_BC_ChannelGreenExpStartPixelLSB,
+ LOBYTE (chip->Timing.ChannelG_StartPixel));
+ Mustek_SendData (chip, ES01_BD_ChannelGreenExpStartPixelMSB,
+ HIBYTE (chip->Timing.ChannelG_StartPixel));
+ Mustek_SendData (chip, ES01_BE_ChannelGreenExpEndPixelLSB,
+ LOBYTE (chip->Timing.ChannelG_EndPixel));
+ Mustek_SendData (chip, ES01_BF_ChannelGreenExpEndPixelMSB,
+ HIBYTE (chip->Timing.ChannelG_EndPixel));
+
+ Mustek_SendData (chip, ES01_C0_ChannelBlueExpStartPixelLSB,
+ LOBYTE (chip->Timing.ChannelB_StartPixel));
+ Mustek_SendData (chip, ES01_C1_ChannelBlueExpStartPixelMSB,
+ HIBYTE (chip->Timing.ChannelB_StartPixel));
+ Mustek_SendData (chip, ES01_C2_ChannelBlueExpEndPixelLSB,
+ LOBYTE (chip->Timing.ChannelB_EndPixel));
+ Mustek_SendData (chip, ES01_C3_ChannelBlueExpEndPixelMSB,
+ HIBYTE (chip->Timing.ChannelB_EndPixel));
+
+ DBG (DBG_ASIC, "SetLEDTime:Exit\n");
+ return status;
+}
+
+static STATUS
+SetScanMode (PAsic chip, SANE_Byte bScanBits)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte temp_f5_register = 0;
+ SANE_Byte GrayBWChannel;
+
+ DBG (DBG_ASIC, "SetScanMode():Enter; set f5 register\n");
+
+ if (bScanBits >= 24)
+ {
+ temp_f5_register |= COLOR_ES02;
+ }
+ else
+ {
+ temp_f5_register |= GRAY_ES02;
+ }
+
+ if ((bScanBits == 8) || (bScanBits == 24))
+ {
+ temp_f5_register |= _8_BITS_ES02;
+ }
+ else if (bScanBits == 1)
+ {
+ temp_f5_register |= _1_BIT_ES02;
+ }
+ else
+ {
+ temp_f5_register |= _16_BITS_ES02;
+ }
+
+ if (bScanBits < 24)
+ {
+ GrayBWChannel = 1;
+ }
+ else
+ {
+ GrayBWChannel = 4;
+ }
+
+ if (GrayBWChannel == 0)
+ {
+ temp_f5_register |= GRAY_RED_ES02;
+ }
+ else if (GrayBWChannel == 1)
+ {
+ temp_f5_register |= GRAY_GREEN_ES02;
+ }
+ else if (GrayBWChannel == 2)
+ {
+ temp_f5_register |= GRAY_BLUE_ES02;
+ }
+ else
+ {
+ temp_f5_register |= GRAY_GREEN_BLUE_ES02;
+ }
+
+ status = Mustek_SendData (chip, ES01_F5_ScanDataFormat, temp_f5_register);
+
+ DBG (DBG_ASIC, "F5_ScanDataFormat=0x%x\n", temp_f5_register);
+ DBG (DBG_ASIC, "SetScanMode():Exit\n");
+ return status;
+}
+
+static STATUS
+SetPackAddress (PAsic chip, unsigned short wXResolution, unsigned short wWidth, unsigned short wX,
+ double XRatioAdderDouble, double XRatioTypeDouble,
+ SANE_Byte byClear_Pulse_Width, unsigned short * PValidPixelNumber)
+{
+ STATUS status = STATUS_GOOD;
+
+ unsigned short LineTotalOverlapPixel;
+ SANE_Byte OverLapPixel;
+ SANE_Byte TotalLineShift;
+ SANE_Byte InvalidPixelNumberBackup;
+ unsigned short SegmentTotalPixel;
+ unsigned int dwLineTotalPixel;
+ unsigned short ValidPixelNumber = *PValidPixelNumber;
+
+ unsigned int FinalLinePixelPerSegment;
+ SANE_Byte InValidPixelNumber;
+ unsigned int CISPackAreaStartAddress;
+ SANE_Byte PackAreaUseLine;
+
+ unsigned int MaxPixelHW;
+ int i;
+
+ DBG (DBG_ASIC, "SetPackAddress:Enter\n");
+
+ LineTotalOverlapPixel = 0;
+ OverLapPixel = 0;
+ TotalLineShift = 1;
+ PackAreaUseLine = TotalLineShift + 1;
+
+ if (wXResolution > (SENSOR_DPI / 2))
+ {
+ ValidPixelNumber = ValidPixelNumberFor1200DPI;
+ OverLapPixel = OverLapPixelNumber1200;
+ }
+ else
+ {
+ ValidPixelNumber = ValidPixelNumberFor600DPI;
+ OverLapPixel = OverLapPixelNumber600;
+ }
+
+ ValidPixelNumber = (unsigned short) ((wWidth + 10 + 15) * XRatioAdderDouble);
+ ValidPixelNumber >>= 4;
+ ValidPixelNumber <<= 4;
+
+ ValidPixelNumber += (OverLapPixel * 2);
+
+ for (i = 0; i < 16; i++)
+ {
+ Mustek_SendData (chip, ES01_2B0_SEGMENT0_OVERLAP_SEGMENT1 + i,
+ OverLapPixel);
+ Mustek_SendData (chip, ES01_2C0_VALID_PIXEL_PARAMETER_OF_SEGMENT1 + i,
+ 0);
+ }
+ LineTotalOverlapPixel = OverLapPixel * 16;
+
+ FinalLinePixelPerSegment = ValidPixelNumber + OverLapPixel * 2;
+
+ if ((FinalLinePixelPerSegment % 8) > 0)
+ {
+ InValidPixelNumber = (SANE_Byte) (8 - (FinalLinePixelPerSegment % 8));
+ }
+ else
+ {
+ InValidPixelNumber = 0;
+ }
+
+ InvalidPixelNumberBackup = InValidPixelNumber;
+
+ Mustek_SendData (chip, ES01_1B0_SEGMENT_PIXEL_NUMBER_LB,
+ LOBYTE (ValidPixelNumber));
+ Mustek_SendData (chip, ES01_1B1_SEGMENT_PIXEL_NUMBER_HB,
+ HIBYTE (ValidPixelNumber));
+
+ SegmentTotalPixel =
+ ValidPixelNumber + OverLapPixel * 2 + InValidPixelNumber;
+
+ Mustek_SendData (chip, ES01_169_NUMBER_OF_SEGMENT_PIXEL_LB,
+ LOBYTE (ValidPixelNumber));
+ Mustek_SendData (chip, ES01_16A_NUMBER_OF_SEGMENT_PIXEL_HB,
+ HIBYTE (ValidPixelNumber));
+ Mustek_SendData (chip, ES01_16B_BETWEEN_SEGMENT_INVALID_PIXEL, 0);
+
+ Mustek_SendData (chip, ES01_B6_LineWidthPixelLSB,
+ LOBYTE (ValidPixelNumber));
+ Mustek_SendData (chip, ES01_B7_LineWidthPixelMSB,
+ HIBYTE (ValidPixelNumber));
+
+ Mustek_SendData (chip, ES01_19A_CHANNEL_LINE_GAP_LB,
+ LOBYTE (ValidPixelNumber));
+ Mustek_SendData (chip, ES01_19B_CHANNEL_LINE_GAP_HB,
+ HIBYTE (ValidPixelNumber));
+ DBG (DBG_ASIC, "ValidPixelNumber=%d\n", ValidPixelNumber);
+
+ for (i = 0; i < 36; i++)
+ {
+ Mustek_SendData (chip, 0x270 + i, 0);
+ }
+
+ Mustek_SendData (chip, 0x270,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) * 1)));
+ Mustek_SendData (chip, 0x271,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) * 1) >> 8));
+ Mustek_SendData (chip, 0x272,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) *
+ 1) >> 16));
+
+ Mustek_SendData (chip, 0x27C,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) * 2)));
+ Mustek_SendData (chip, 0x27D,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) * 2) >> 8));
+ Mustek_SendData (chip, 0x27E,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) *
+ 2) >> 16));
+
+ Mustek_SendData (chip, 0x288,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) * 3)));
+ Mustek_SendData (chip, 0x289,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) * 3) >> 8));
+ Mustek_SendData (chip, 0x28A,
+ (SANE_Byte) ((SegmentTotalPixel * (PackAreaUseLine) *
+ 3) >> 16));
+ DBG (DBG_ASIC, "channel gap=%d\n", SegmentTotalPixel * (PackAreaUseLine));
+
+
+ Mustek_SendData (chip, ES01_B4_StartPixelLSB, LOBYTE (wX + 0));
+ Mustek_SendData (chip, ES01_B5_StartPixelMSB, HIBYTE (wX + 0));
+
+
+ dwLineTotalPixel = ValidPixelNumber;
+
+ Mustek_SendData (chip, ES01_1B9_LINE_PIXEL_NUMBER_LB,
+ LOBYTE (XRatioTypeDouble * (dwLineTotalPixel - 1)));
+ Mustek_SendData (chip, ES01_1BA_LINE_PIXEL_NUMBER_HB,
+ HIBYTE (XRatioTypeDouble * (dwLineTotalPixel - 1)));
+
+ /* final start read out pixel */
+ Mustek_SendData (chip, ES01_1F4_START_READ_OUT_PIXEL_LB, LOBYTE (0));
+ Mustek_SendData (chip, ES01_1F5_START_READ_OUT_PIXEL_HB, HIBYTE (0));
+
+ MaxPixelHW = (dwLineTotalPixel + InValidPixelNumber) - 10;
+
+ if (wWidth > MaxPixelHW)
+ {
+ DBG (DBG_ERR, "read out pixel over max pixel! image will shift!!!\n");
+ }
+
+ /* final read pixel width */
+ Mustek_SendData (chip, ES01_1F6_READ_OUT_PIXEL_LENGTH_LB,
+ LOBYTE (wWidth + 9));
+ Mustek_SendData (chip, ES01_1F7_READ_OUT_PIXEL_LENGTH_HB,
+ HIBYTE (wWidth + 9));
+
+ /* data output sequence */
+ Mustek_SendData (chip, ES01_1F8_PACK_CHANNEL_SELECT_B0, 0);
+ Mustek_SendData (chip, ES01_1F9_PACK_CHANNEL_SELECT_B1, 0);
+ Mustek_SendData (chip, ES01_1FA_PACK_CHANNEL_SELECT_B2, 0x18);
+
+ Mustek_SendData (chip, ES01_1FB_PACK_CHANNEL_SIZE_B0,
+ (SANE_Byte) ((SegmentTotalPixel * PackAreaUseLine)));
+ Mustek_SendData (chip, ES01_1FC_PACK_CHANNEL_SIZE_B1,
+ (SANE_Byte) ((SegmentTotalPixel * PackAreaUseLine) >> 8));
+ Mustek_SendData (chip, ES01_1FD_PACK_CHANNEL_SIZE_B2,
+ (SANE_Byte) ((SegmentTotalPixel * PackAreaUseLine) >> 16));
+
+ Mustek_SendData (chip, ES01_16C_LINE_SHIFT_OUT_TIMES_DIRECTION, 0x01);
+ Mustek_SendData (chip, ES01_1CE_LINE_SEGMENT_NUMBER, 0x00);
+ Mustek_SendData (chip, ES01_D8_PHTG_EDGE_TIMING_ADJUST, 0x17);
+
+ Mustek_SendData (chip, ES01_D9_CLEAR_PULSE_WIDTH, byClear_Pulse_Width);
+
+ Mustek_SendData (chip, ES01_DA_CLEAR_SIGNAL_INVERTING_OUTPUT, 0x54 | 0x01);
+ Mustek_SendData (chip, ES01_CD_TG_R_CONTROL, 0x3C);
+ Mustek_SendData (chip, ES01_CE_TG_G_CONTROL, 0);
+ Mustek_SendData (chip, ES01_CF_TG_B_CONTROL, 0x3C);
+
+
+ /* set pack area address */
+
+ CISPackAreaStartAddress = PackAreaStartAddress;
+ DBG (DBG_ASIC, "CISPackAreaStartAddress=%d\n", CISPackAreaStartAddress);
+
+ /* cycle 1 */
+ Mustek_SendData (chip, ES01_16D_EXPOSURE_CYCLE1_SEGMENT1_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0)));
+ Mustek_SendData (chip, ES01_16E_EXPOSURE_CYCLE1_SEGMENT1_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0) >> 8));
+ Mustek_SendData (chip, ES01_16F_EXPOSURE_CYCLE1_SEGMENT1_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0) >> 16));
+
+ Mustek_SendData (chip, ES01_170_EXPOSURE_CYCLE1_SEGMENT2_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_171_EXPOSURE_CYCLE1_SEGMENT2_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_172_EXPOSURE_CYCLE1_SEGMENT2_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ Mustek_SendData (chip, ES01_173_EXPOSURE_CYCLE1_SEGMENT3_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_174_EXPOSURE_CYCLE1_SEGMENT3_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_175_EXPOSURE_CYCLE1_SEGMENT3_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ Mustek_SendData (chip, ES01_176_EXPOSURE_CYCLE1_SEGMENT4_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_177_EXPOSURE_CYCLE1_SEGMENT4_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_178_EXPOSURE_CYCLE1_SEGMENT4_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ /* cycle 2 */
+ Mustek_SendData (chip, ES01_179_EXPOSURE_CYCLE2_SEGMENT1_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_17A_EXPOSURE_CYCLE2_SEGMENT1_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_17B_EXPOSURE_CYCLE2_SEGMENT1_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ Mustek_SendData (chip, ES01_17C_EXPOSURE_CYCLE2_SEGMENT2_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_17D_EXPOSURE_CYCLE2_SEGMENT2_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_17E_EXPOSURE_CYCLE2_SEGMENT2_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ Mustek_SendData (chip, ES01_17F_EXPOSURE_CYCLE2_SEGMENT3_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_180_EXPOSURE_CYCLE2_SEGMENT3_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_181_EXPOSURE_CYCLE2_SEGMENT3_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ Mustek_SendData (chip, ES01_182_EXPOSURE_CYCLE2_SEGMENT4_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_183_EXPOSURE_CYCLE2_SEGMENT4_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_184_EXPOSURE_CYCLE2_SEGMENT4_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ /* cycle 3 */
+ Mustek_SendData (chip, ES01_185_EXPOSURE_CYCLE3_SEGMENT1_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+
+ Mustek_SendData (chip, ES01_186_EXPOSURE_CYCLE3_SEGMENT1_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_187_EXPOSURE_CYCLE3_SEGMENT1_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ Mustek_SendData (chip, ES01_188_EXPOSURE_CYCLE3_SEGMENT2_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_189_EXPOSURE_CYCLE3_SEGMENT2_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_18A_EXPOSURE_CYCLE3_SEGMENT2_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ Mustek_SendData (chip, ES01_18B_EXPOSURE_CYCLE3_SEGMENT3_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_18C_EXPOSURE_CYCLE3_SEGMENT3_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_18D_EXPOSURE_CYCLE3_SEGMENT3_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+
+ Mustek_SendData (chip, ES01_18E_EXPOSURE_CYCLE3_SEGMENT4_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000)));
+ Mustek_SendData (chip, ES01_18F_EXPOSURE_CYCLE3_SEGMENT4_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 8));
+ Mustek_SendData (chip, ES01_190_EXPOSURE_CYCLE3_SEGMENT4_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress + 0xC0000) >> 16));
+ DBG (DBG_ASIC, "set CISPackAreaStartAddress ok\n");
+
+ Mustek_SendData (chip, 0x260, InValidPixelNumber);
+ Mustek_SendData (chip, 0x261, InValidPixelNumber << 4);
+ Mustek_SendData (chip, 0x262, InValidPixelNumber);
+ Mustek_SendData (chip, 0x263, 0);
+ DBG (DBG_ASIC, "InValidPixelNumber=%d\n", InValidPixelNumber);
+
+ Mustek_SendData (chip, 0x264, 0);
+ Mustek_SendData (chip, 0x265, 0);
+ Mustek_SendData (chip, 0x266, 0);
+ Mustek_SendData (chip, 0x267, 0);
+
+ Mustek_SendData (chip, 0x268, 0);
+ Mustek_SendData (chip, 0x269, 0);
+ Mustek_SendData (chip, 0x26A, 0);
+ Mustek_SendData (chip, 0x26B, 0);
+
+ Mustek_SendData (chip, 0x26C, 0);
+ Mustek_SendData (chip, 0x26D, 0);
+ Mustek_SendData (chip, 0x26E, 0);
+ Mustek_SendData (chip, 0x26F, 0);
+ DBG (DBG_ASIC, "Set Invalid Pixel ok\n");
+
+
+ /* Pack Start Address */
+ Mustek_SendData (chip, ES01_19E_PACK_AREA_R_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 0)))));
+ Mustek_SendData (chip, ES01_19F_PACK_AREA_R_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel *
+ (PackAreaUseLine * 0))) >> 8));
+ Mustek_SendData (chip, ES01_1A0_PACK_AREA_R_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel *
+ (PackAreaUseLine * 0))) >> 16));
+
+
+ Mustek_SendData (chip, ES01_1A1_PACK_AREA_G_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 1)))));
+ Mustek_SendData (chip, ES01_1A2_PACK_AREA_G_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel *
+ (PackAreaUseLine * 1))) >> 8));
+ Mustek_SendData (chip, ES01_1A3_PACK_AREA_G_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel *
+ (PackAreaUseLine * 1))) >> 16));
+
+ Mustek_SendData (chip, ES01_1A4_PACK_AREA_B_START_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 2)))));
+ Mustek_SendData (chip, ES01_1A5_PACK_AREA_B_START_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel *
+ (PackAreaUseLine * 2))) >> 8));
+ Mustek_SendData (chip, ES01_1A6_PACK_AREA_B_START_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel *
+ (PackAreaUseLine * 2))) >> 16));
+
+ /* Pack End Address */
+ Mustek_SendData (chip, ES01_1A7_PACK_AREA_R_END_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 1) -
+ 1))));
+ Mustek_SendData (chip, ES01_1A8_PACK_AREA_R_END_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 1) -
+ 1)) >> 8));
+ Mustek_SendData (chip, ES01_1A9_PACK_AREA_R_END_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 1) -
+ 1)) >> 16));
+
+ Mustek_SendData (chip, ES01_1AA_PACK_AREA_G_END_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 2) -
+ 1))));
+ Mustek_SendData (chip, ES01_1AB_PACK_AREA_G_END_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 2) -
+ 1)) >> 8));
+ Mustek_SendData (chip, ES01_1AC_PACK_AREA_G_END_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 2) -
+ 1)) >> 16));
+
+ Mustek_SendData (chip, ES01_1AD_PACK_AREA_B_END_ADDR_BYTE0,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 3) -
+ 1))));
+ Mustek_SendData (chip, ES01_1AE_PACK_AREA_B_END_ADDR_BYTE1,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 3) -
+ 1)) >> 8));
+ Mustek_SendData (chip, ES01_1AF_PACK_AREA_B_END_ADDR_BYTE2,
+ (SANE_Byte) ((CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 3) -
+ 1)) >> 16));
+ DBG (DBG_ASIC,
+ "CISPackAreaStartAddress + (SegmentTotalPixel*(PackAreaUseLine*1))=%d\n",
+ (CISPackAreaStartAddress +
+ (SegmentTotalPixel * (PackAreaUseLine * 1))));
+
+ Mustek_SendData (chip, ES01_19C_MAX_PACK_LINE, PackAreaUseLine);
+
+ status =
+ Mustek_SendData (chip, ES01_19D_PACK_THRESHOLD_LINE, TotalLineShift);
+ DBG (DBG_ASIC, "PackAreaUseLine=%d,TotalLineShift=%d\n", PackAreaUseLine,
+ TotalLineShift);
+
+ *PValidPixelNumber = ValidPixelNumber;
+
+ DBG (DBG_ASIC, "SetPackAddress:Enter\n");
+ return status;
+}
+
+static STATUS
+SetExtraSetting (PAsic chip, unsigned short wXResolution, unsigned short wCCD_PixelNumber,
+ SANE_Bool isCaribrate)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte byPHTG_PulseWidth, byPHTG_WaitWidth;
+ SANE_Byte temp_ff_register = 0;
+ SANE_Byte bThreshold = 128;
+
+ DBG (DBG_ASIC, "SetExtraSetting:Enter\n");
+
+ Mustek_SendData (chip, ES01_B8_ChannelRedExpStartPixelLSB,
+ LOBYTE (chip->Timing.ChannelR_StartPixel));
+ Mustek_SendData (chip, ES01_B9_ChannelRedExpStartPixelMSB,
+ HIBYTE (chip->Timing.ChannelR_StartPixel));
+ Mustek_SendData (chip, ES01_BA_ChannelRedExpEndPixelLSB,
+ LOBYTE (chip->Timing.ChannelR_EndPixel));
+ Mustek_SendData (chip, ES01_BB_ChannelRedExpEndPixelMSB,
+ HIBYTE (chip->Timing.ChannelR_EndPixel));
+
+ Mustek_SendData (chip, ES01_BC_ChannelGreenExpStartPixelLSB,
+ LOBYTE (chip->Timing.ChannelG_StartPixel));
+ Mustek_SendData (chip, ES01_BD_ChannelGreenExpStartPixelMSB,
+ HIBYTE (chip->Timing.ChannelG_StartPixel));
+ Mustek_SendData (chip, ES01_BE_ChannelGreenExpEndPixelLSB,
+ LOBYTE (chip->Timing.ChannelG_EndPixel));
+ Mustek_SendData (chip, ES01_BF_ChannelGreenExpEndPixelMSB,
+ HIBYTE (chip->Timing.ChannelG_EndPixel));
+
+ Mustek_SendData (chip, ES01_C0_ChannelBlueExpStartPixelLSB,
+ LOBYTE (chip->Timing.ChannelB_StartPixel));
+ Mustek_SendData (chip, ES01_C1_ChannelBlueExpStartPixelMSB,
+ HIBYTE (chip->Timing.ChannelB_StartPixel));
+ Mustek_SendData (chip, ES01_C2_ChannelBlueExpEndPixelLSB,
+ LOBYTE (chip->Timing.ChannelB_EndPixel));
+ Mustek_SendData (chip, ES01_C3_ChannelBlueExpEndPixelMSB,
+ HIBYTE (chip->Timing.ChannelB_EndPixel));
+
+ byPHTG_PulseWidth = chip->Timing.PHTG_PluseWidth;
+ byPHTG_WaitWidth = chip->Timing.PHTG_WaitWidth;
+ Mustek_SendData (chip, ES01_B2_PHTGPulseWidth, byPHTG_PulseWidth);
+ Mustek_SendData (chip, ES01_B3_PHTGWaitWidth, byPHTG_WaitWidth);
+
+ Mustek_SendData (chip, ES01_CC_PHTGTimingAdjust,
+ chip->Timing.PHTG_TimingAdj);
+ Mustek_SendData (chip, ES01_D0_PH1_0, chip->Timing.PHTG_TimingSetup);
+
+ DBG (DBG_ASIC, "ChannelR_StartPixel=%d,ChannelR_EndPixel=%d\n",
+ chip->Timing.ChannelR_StartPixel, chip->Timing.ChannelR_EndPixel);
+
+ if (wXResolution == 1200)
+ {
+ Mustek_SendData (chip, ES01_DE_CCD_SETUP_REGISTER,
+ chip->Timing.DE_CCD_SETUP_REGISTER_1200);
+ }
+ else
+ {
+ Mustek_SendData (chip, ES01_DE_CCD_SETUP_REGISTER,
+ chip->Timing.DE_CCD_SETUP_REGISTER_600);
+ }
+
+ if (isCaribrate == TRUE)
+ {
+ temp_ff_register |= BYPASS_DARK_SHADING_ENABLE;
+ temp_ff_register |= BYPASS_WHITE_SHADING_ENABLE;
+ }
+ else /*Setwindow */
+ {
+ temp_ff_register |= BYPASS_DARK_SHADING_DISABLE;
+ temp_ff_register |= BYPASS_WHITE_SHADING_DISABLE;
+ }
+
+ temp_ff_register |= BYPASS_PRE_GAMMA_ENABLE;
+
+ temp_ff_register |= BYPASS_CONVOLUTION_ENABLE;
+
+
+ temp_ff_register |= BYPASS_MATRIX_ENABLE;
+
+ temp_ff_register |= BYPASS_GAMMA_ENABLE;
+
+ if (isCaribrate == TRUE)
+ {
+ Mustek_SendData (chip, ES01_FF_SCAN_IMAGE_OPTION, 0xfc | (0x00 & 0x03));
+ DBG (DBG_ASIC, "FF_SCAN_IMAGE_OPTION=0x%x\n", 0xfc | (0x00 & 0x03));
+ }
+ else /*Setwindow */
+ {
+ Mustek_SendData (chip, ES01_FF_SCAN_IMAGE_OPTION,
+ temp_ff_register | (0x00 & 0x03));
+ DBG (DBG_ASIC, "FF_SCAN_IMAGE_OPTION=0x%x\n",
+ temp_ff_register | (0x00 & 0x03));
+ }
+
+ /* pixel process time */
+ Mustek_SendData (chip, ES01_B0_CCDPixelLSB, LOBYTE (wCCD_PixelNumber));
+ Mustek_SendData (chip, ES01_B1_CCDPixelMSB, HIBYTE (wCCD_PixelNumber));
+ Mustek_SendData (chip, ES01_DF_ICG_CONTROL, 0x17);
+ DBG (DBG_ASIC, "wCCD_PixelNumber=%d\n", wCCD_PixelNumber);
+
+ Mustek_SendData (chip, ES01_88_LINE_ART_THRESHOLD_HIGH_VALUE, bThreshold);
+ Mustek_SendData (chip, ES01_89_LINE_ART_THRESHOLD_LOW_VALUE,
+ bThreshold - 1);
+ DBG (DBG_ASIC, "bThreshold=%d\n", bThreshold);
+
+ usleep (50000);
+
+ DBG (DBG_ASIC, "SetExtraSetting:Exit\n");
+ return status;
+}
+
+
+/* ---------------------- high level asic functions ------------------------ */
+
+
+/* HOLD: We don't want to have global vid/pids */
+static unsigned short ProductID = 0x0409;
+static unsigned short VendorID = 0x055f;
+
+static SANE_String_Const device_name;
+
+static SANE_Status
+attach_one_scanner (SANE_String_Const devname)
+{
+ DBG (DBG_ASIC, "attach_one_scanner: enter\n");
+ DBG (DBG_INFO, "attach_one_scanner: devname = %s\n", devname);
+ device_name = devname;
+ return SANE_STATUS_GOOD;
+}
+
+static STATUS
+Asic_Open (PAsic chip, SANE_Byte *pDeviceName)
+{
+ STATUS status;
+ SANE_Status sane_status;
+
+ DBG (DBG_ASIC, "Asic_Open: Enter\n");
+
+ device_name = NULL;
+
+ if (chip->firmwarestate > FS_OPENED)
+ {
+ DBG (DBG_ASIC, "chip has been opened. fd=%d\n", chip->fd);
+ return STATUS_INVAL;
+ }
+
+ /* init usb */
+ sanei_usb_init ();
+
+ /* find scanner */
+ sane_status =
+ sanei_usb_find_devices (VendorID, ProductID, attach_one_scanner);
+ if (sane_status != SANE_STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Asic_Open: sanei_usb_find_devices failed: %s\n",
+ sane_strstatus (sane_status));
+ return STATUS_INVAL;
+ }
+ /* open usb */
+ if (device_name == NULL)
+ {
+ DBG (DBG_ERR, "Asic_Open: no scanner found\n");
+ return STATUS_INVAL;
+ }
+ sane_status = sanei_usb_open (device_name, &chip->fd);
+ if (sane_status != SANE_STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Asic_Open: sanei_usb_open of %s failed: %s\n",
+ device_name, sane_strstatus (sane_status));
+ return STATUS_INVAL;
+ }
+
+ /* open scanner chip */
+ status = OpenScanChip (chip);
+ if (status != STATUS_GOOD)
+ {
+ sanei_usb_close (chip->fd);
+ DBG (DBG_ASIC, "Asic_Open: OpenScanChip error\n");
+ return status;
+ }
+
+ Mustek_SendData (chip, ES01_94_PowerSaveControl, 0x27);
+ Mustek_SendData (chip, ES01_86_DisableAllClockWhenIdle,
+ CLOSE_ALL_CLOCK_DISABLE);
+ Mustek_SendData (chip, ES01_79_AFEMCLK_SDRAMCLK_DELAY_CONTROL,
+ SDRAMCLK_DELAY_12_ns);
+
+ /* SDRAM initial sequence */
+ Mustek_SendData (chip, ES01_87_SDRAM_Timing, 0xf1);
+ Mustek_SendData (chip, ES01_87_SDRAM_Timing, 0xa5);
+ Mustek_SendData (chip, ES01_87_SDRAM_Timing, 0x91);
+ Mustek_SendData (chip, ES01_87_SDRAM_Timing, 0x81);
+ Mustek_SendData (chip, ES01_87_SDRAM_Timing, 0xf0);
+
+
+ chip->firmwarestate = FS_OPENED;
+ Asic_WaitUnitReady (chip);
+ DBG (DBG_ASIC, "Asic_WaitUnitReady\n");
+ status = SafeInitialChip (chip);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Asic_Open: SafeInitialChip error\n");
+ return status;
+ }
+
+ pDeviceName = (SANE_Byte *) strdup (device_name);
+ if (!pDeviceName)
+ {
+ DBG (DBG_ERR, "Asic_Open: not enough memory\n");
+ return STATUS_INVAL;
+ }
+ DBG (DBG_INFO, "Asic_Open: device %s successfully opened\n", pDeviceName);
+ DBG (DBG_ASIC, "Asic_Open: Exit\n");
+ return status;
+}
+
+
+static STATUS
+Asic_Close (PAsic chip)
+{
+ STATUS status;
+ DBG (DBG_ASIC, "Asic_Close: Enter\n");
+
+ if (chip->firmwarestate < FS_OPENED)
+ {
+ DBG (DBG_ASIC, "Asic_Close: Scanner is not opened\n");
+ return STATUS_GOOD;
+ }
+
+ if (chip->firmwarestate > FS_OPENED)
+ {
+ DBG (DBG_ASIC,
+ "Asic_Close: Scanner is scanning, try to stop scanning\n");
+ Asic_ScanStop (chip);
+ }
+
+ Mustek_SendData (chip, ES01_86_DisableAllClockWhenIdle,
+ CLOSE_ALL_CLOCK_ENABLE);
+
+ status = CloseScanChip (chip);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Asic_Close: CloseScanChip error\n");
+ return status;
+ }
+
+ sanei_usb_close (chip->fd);
+ chip->firmwarestate = FS_ATTACHED;
+
+ DBG (DBG_ASIC, "Asic_Close: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_TurnLamp (PAsic chip, SANE_Bool isLampOn)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte PWM;
+
+ DBG (DBG_ASIC, "Asic_TurnLamp: Enter\n");
+
+ if (chip->firmwarestate < FS_OPENED)
+ {
+ DBG (DBG_ERR, "Asic_TurnLamp: Scanner is not opened\n");
+ return STATUS_INVAL;
+ }
+
+ if (chip->firmwarestate > FS_OPENED)
+ {
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+ }
+
+ if (isLampOn)
+ {
+ PWM = LAMP0_PWM_DEFAULT;
+ }
+ else
+ {
+ PWM = 0;
+ }
+ Mustek_SendData (chip, ES01_99_LAMP_PWM_FREQ_CONTROL, 1);
+ Mustek_SendData (chip, ES01_90_Lamp0PWM, PWM);
+ DBG (DBG_ASIC, "Lamp0 PWM = %d\n", PWM);
+
+ chip->firmwarestate = FS_OPENED;
+
+ DBG (DBG_ASIC, "Asic_TurnLamp: Exit\n");
+ return status;
+}
+
+
+static STATUS
+Asic_TurnTA (PAsic chip, SANE_Bool isTAOn)
+{
+ SANE_Byte PWM;
+
+ DBG (DBG_ASIC, "Asic_TurnTA: Enter\n");
+
+ if (chip->firmwarestate < FS_OPENED)
+ {
+ DBG (DBG_ERR, "Asic_TurnTA: Scanner is not opened\n");
+ return STATUS_INVAL;
+ }
+
+ if (chip->firmwarestate > FS_OPENED)
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+
+ if (isTAOn)
+ {
+ PWM = LAMP1_PWM_DEFAULT;
+ }
+ else
+ {
+ PWM = 0;
+
+ }
+ Mustek_SendData (chip, ES01_99_LAMP_PWM_FREQ_CONTROL, 1);
+ Mustek_SendData (chip, ES01_91_Lamp1PWM, PWM);
+ DBG (DBG_ASIC, "Lamp1 PWM = %d\n", PWM);
+
+ chip->firmwarestate = FS_OPENED;
+ DBG (DBG_ASIC, "Asic_TurnTA: Exit\n");
+ return STATUS_GOOD;
+}
+
+static STATUS
+Asic_WaitUnitReady (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte temp_status;
+ int i = 0;
+
+ DBG (DBG_ASIC, "Asic_WaitUnitReady:Enter\n");
+
+ if (chip->firmwarestate < FS_OPENED)
+ {
+ DBG (DBG_ERR, "Asic_WaitUnitReady: Scanner has not been opened\n");
+
+ return STATUS_INVAL;
+ }
+
+
+ do
+ {
+ status = GetChipStatus (chip, 1, &temp_status);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ASIC, "WaitChipIdle:Error!\n");
+ return status;
+ }
+ i++;
+ usleep (100000);
+ }
+ while (((temp_status & 0x1f) != 0) && i < 300);
+ DBG (DBG_ASIC, "Wait %d s\n", (unsigned short) (i * 0.1));
+
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+ chip->motorstate = MS_STILL;
+
+ DBG (DBG_ASIC, "Asic_WaitUnitReady: Exit\n");
+ return status;
+}
+
+#if SANE_UNUSED
+static STATUS
+Asic_Release (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "Asic_Release()\n");
+
+ if (chip->firmwarestate > FS_ATTACHED)
+ status = Asic_Close (chip);
+
+ chip->firmwarestate = FS_NULL;
+
+ DBG (DBG_ASIC, "Asic_Release: Exit\n");
+ return status;
+}
+#endif
+
+static STATUS
+Asic_Initialize (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "Asic_Initialize:Enter\n");
+
+
+ chip->motorstate = MS_STILL;
+ chip->dwBytesCountPerRow = 0;
+ chip->lpGammaTable = NULL;
+ DBG (DBG_ASIC, "isFirstOpenChip=%d\n", chip->isFirstOpenChip);
+
+ chip->isFirstOpenChip = TRUE;
+ DBG (DBG_ASIC, "isFirstOpenChip=%d\n", chip->isFirstOpenChip);
+
+ chip->SWWidth = 0;
+ chip->TA_Status = TA_UNKNOW;
+ chip->lpShadingTable = NULL;
+ chip->isMotorMove = MOTOR_0_ENABLE;
+
+ Asic_Reset (chip);
+ InitTiming (chip);
+
+ chip->isUniformSpeedToScan = UNIFORM_MOTOR_AND_SCAN_SPEED_DISABLE;
+ chip->isMotorGoToFirstLine = MOTOR_MOVE_TO_FIRST_LINE_ENABLE;
+
+ chip->UsbHost = HT_USB10;
+
+ DBG (DBG_ASIC, "Asic_Initialize: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_SetWindow (PAsic chip, SANE_Byte bScanBits,
+ unsigned short wXResolution, unsigned short wYResolution,
+ unsigned short wX, unsigned short wY, unsigned short wWidth, unsigned short wLength)
+{
+ STATUS status = STATUS_GOOD;
+
+ unsigned short ValidPixelNumber;
+
+ unsigned short wPerLineNeedBufferSize = 0;
+ unsigned short BytePerPixel = 0;
+ unsigned int dwTotal_PerLineNeedBufferSize = 0;
+ unsigned int dwTotalLineTheBufferNeed = 0;
+ unsigned short dwTotal_CCDResolution = 1200;
+ unsigned short wThinkCCDResolution = 0;
+ unsigned short wCCD_PixelNumber = 0;
+ unsigned int dwLineWidthPixel = 0;
+ unsigned short wNowMotorDPI;
+ unsigned short XRatioTypeWord;
+ double XRatioTypeDouble;
+ double XRatioAdderDouble;
+
+ LLF_MOTORMOVE *lpMotorStepsTable =
+ (LLF_MOTORMOVE *) malloc (sizeof (LLF_MOTORMOVE));
+ SANE_Byte byDummyCycleNum = 0;
+ unsigned short Total_MotorDPI;
+
+ unsigned short wMultiMotorStep = 1;
+ SANE_Byte bMotorMoveType = _MOTOR_MOVE_TYPE;
+
+ SANE_Byte byClear_Pulse_Width = 0;
+
+ unsigned int dwLinePixelReport;
+ SANE_Byte byPHTG_PulseWidth, byPHTG_WaitWidth;
+
+ unsigned short StartSpeed, EndSpeed;
+ LLF_CALCULATEMOTORTABLE CalMotorTable;
+ LLF_MOTOR_CURRENT_AND_PHASE CurrentPhase;
+ LLF_RAMACCESS RamAccess;
+ unsigned int dwStartAddr, dwEndAddr, dwTableBaseAddr, dwShadingTableAddr;
+
+ SANE_Byte isMotorMoveToFirstLine = chip->isMotorGoToFirstLine;
+ SANE_Byte isUniformSpeedToScan = chip->isUniformSpeedToScan;
+ SANE_Byte isScanBackTracking = SCAN_BACK_TRACKING_ENABLE;
+ unsigned short * lpMotorTable;
+ unsigned int RealTableSize;
+ double dbXRatioAdderDouble;
+ unsigned short wFullBank;
+
+ DBG (DBG_ASIC, "Asic_SetWindow: Enter\n");
+ DBG (DBG_ASIC,
+ "bScanBits=%d,wXResolution=%d,wYResolution=%d,wX=%d,wY=%d,wWidth=%d,wLength=%d\n",
+ bScanBits, wXResolution, wYResolution, wX, wY, wWidth, wLength);
+
+ if (chip->firmwarestate != FS_OPENED)
+ {
+ DBG (DBG_ERR, "Asic_SetWindow: Scanner is not opened\n");
+ return STATUS_INVAL;
+ }
+
+ Mustek_SendData (chip, ES01_F3_ActionOption, 0);
+ Mustek_SendData (chip, ES01_86_DisableAllClockWhenIdle,
+ CLOSE_ALL_CLOCK_DISABLE);
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+
+ status = Asic_WaitUnitReady (chip);
+
+ /* dummy clock mode */
+ Mustek_SendData (chip, 0x1CD, 0);
+
+ /* LED Flash */
+ Mustek_SendData (chip, ES01_94_PowerSaveControl, 0x27 | 64 | 128);
+
+ /* calculate byte per line */
+ if (bScanBits > 24)
+ {
+ wPerLineNeedBufferSize = wWidth * 6;
+ BytePerPixel = 6;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth) * 6;
+ }
+ else if (bScanBits == 24)
+ {
+ wPerLineNeedBufferSize = wWidth * 3;
+ BytePerPixel = 3;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth) * 3;
+ }
+ else if ((bScanBits > 8) && (bScanBits <= 16))
+ {
+ wPerLineNeedBufferSize = wWidth * 2;
+ BytePerPixel = 2;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth) * 2;
+ }
+ else if ((bScanBits == 8))
+ {
+ wPerLineNeedBufferSize = wWidth;
+ BytePerPixel = 1;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth);
+ }
+ else if ((bScanBits < 8))
+ {
+ wPerLineNeedBufferSize = wWidth >> 3;
+ BytePerPixel = 1;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth);
+ }
+ DBG (DBG_ASIC, "dwBytesCountPerRow = %d\n", chip->dwBytesCountPerRow);
+
+ byDummyCycleNum = 0;
+ if (chip->lsLightSource == LS_REFLECTIVE)
+ {
+ if (chip->UsbHost == HT_USB10)
+ {
+ switch (wYResolution)
+ {
+ case 2400:
+ case 1200:
+ if (chip->dwBytesCountPerRow > 22000)
+ byDummyCycleNum = 4;
+ else if (chip->dwBytesCountPerRow > 15000)
+ byDummyCycleNum = 3;
+ else if (chip->dwBytesCountPerRow > 10000)
+ byDummyCycleNum = 2;
+ else if (chip->dwBytesCountPerRow > 5000)
+ byDummyCycleNum = 1;
+ break;
+ case 600:
+ case 300:
+ case 150:
+ case 100:
+ if (chip->dwBytesCountPerRow > 21000)
+ byDummyCycleNum = 7;
+ else if (chip->dwBytesCountPerRow > 18000)
+ byDummyCycleNum = 6;
+ else if (chip->dwBytesCountPerRow > 15000)
+ byDummyCycleNum = 5;
+ else if (chip->dwBytesCountPerRow > 12000)
+ byDummyCycleNum = 4;
+ else if (chip->dwBytesCountPerRow > 9000)
+ byDummyCycleNum = 3;
+ else if (chip->dwBytesCountPerRow > 6000)
+ byDummyCycleNum = 2;
+ else if (chip->dwBytesCountPerRow > 3000)
+ byDummyCycleNum = 1;
+ break;
+ case 75:
+ case 50:
+ byDummyCycleNum = 1;
+ break;
+ default:
+ byDummyCycleNum = 0;
+ break;
+ }
+ }
+ else
+ {
+ switch (wYResolution)
+ {
+ case 2400:
+ case 1200:
+ case 75:
+ case 50:
+ byDummyCycleNum = 1;
+ break;
+ default:
+ byDummyCycleNum = 0;
+ break;
+ }
+ }
+ }
+
+ dwTotal_PerLineNeedBufferSize = wPerLineNeedBufferSize;
+ dwTotalLineTheBufferNeed = wLength;
+
+ chip->Scan.Dpi = wXResolution;
+ CCDTiming (chip);
+
+ dwTotal_CCDResolution = SENSOR_DPI;
+
+ if (chip->lsLightSource == LS_REFLECTIVE)
+ {
+ if (wXResolution > (dwTotal_CCDResolution / 2))
+ { /* full ccd resolution 1200dpi */
+ wThinkCCDResolution = dwTotal_CCDResolution;
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x01);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x01);
+
+ wCCD_PixelNumber = chip->Timing.wCCDPixelNumber_1200;
+ }
+ else
+ { /*600dpi */
+ wThinkCCDResolution = dwTotal_CCDResolution / 2;
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x01);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x00);
+ wCCD_PixelNumber = chip->Timing.wCCDPixelNumber_600;
+ }
+ }
+ else
+ {
+ if (wXResolution > (dwTotal_CCDResolution / 2))
+ {
+ wThinkCCDResolution = dwTotal_CCDResolution;
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x01);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x01);
+ wCCD_PixelNumber = TA_IMAGE_PIXELNUMBER;
+ }
+ else
+ {
+ wThinkCCDResolution = dwTotal_CCDResolution / 2;
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x01);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x00);
+ wCCD_PixelNumber = TA_IMAGE_PIXELNUMBER;
+ }
+ }
+
+ dwLineWidthPixel = wWidth;
+
+ SetLineTimeAndExposure (chip);
+
+ Mustek_SendData (chip, ES01_CB_CCDDummyCycleNumber, byDummyCycleNum);
+
+
+ SetLEDTime (chip);
+
+ /* calculate Y ratio */
+ Total_MotorDPI = 1200;
+ wNowMotorDPI = Total_MotorDPI;
+
+
+ /* SetADConverter */
+ Mustek_SendData (chip, ES01_74_HARDWARE_SETTING,
+ MOTOR1_SERIAL_INTERFACE_G10_8_ENABLE | LED_OUT_G11_DISABLE
+ | SLAVE_SERIAL_INTERFACE_G15_14_DISABLE |
+ SHUTTLE_CCD_DISABLE);
+
+ /* set AFE */
+ Mustek_SendData (chip, ES01_9A_AFEControl,
+ AD9826_AFE | AUTO_CHANGE_AFE_GAIN_OFFSET_DISABLE);
+ SetAFEGainOffset (chip);
+
+ Mustek_SendData (chip, ES01_F7_DigitalControl, DIGITAL_REDUCE_DISABLE);
+
+ /* calculate X ratio */
+ XRatioTypeDouble = wXResolution;
+ XRatioTypeDouble /= wThinkCCDResolution;
+ XRatioAdderDouble = 1 / XRatioTypeDouble;
+ XRatioTypeWord = (unsigned short) (XRatioTypeDouble * 32768); /* 32768 = 2^15 */
+
+ XRatioAdderDouble = (double) (XRatioTypeWord) / 32768;
+ XRatioAdderDouble = 1 / XRatioAdderDouble;
+
+ /* 0x8000 = 1.00000 -> get all pixel */
+ Mustek_SendData (chip, ES01_9E_HorizontalRatio1to15LSB,
+ LOBYTE (XRatioTypeWord));
+ Mustek_SendData (chip, ES01_9F_HorizontalRatio1to15MSB,
+ HIBYTE (XRatioTypeWord));
+
+ /* SetMotorType */
+ Mustek_SendData (chip, ES01_A6_MotorOption, MOTOR_0_ENABLE |
+ MOTOR_1_DISABLE |
+ HOME_SENSOR_0_ENABLE | ES03_TABLE_DEFINE);
+
+ Mustek_SendData (chip, ES01_F6_MorotControl1, SPEED_UNIT_1_PIXEL_TIME |
+ MOTOR_SYNC_UNIT_1_PIXEL_TIME);
+
+ /* SetScanStepTable */
+
+ /*set Motor move type */
+ if (wYResolution >= 1200)
+ bMotorMoveType = _8_TABLE_SPACE_FOR_1_DIV_2_STEP;
+
+ switch (bMotorMoveType)
+ {
+ case _4_TABLE_SPACE_FOR_FULL_STEP:
+ wMultiMotorStep = 1;
+ break;
+
+ case _8_TABLE_SPACE_FOR_1_DIV_2_STEP:
+ wMultiMotorStep = 2;
+ break;
+
+ case _16_TABLE_SPACE_FOR_1_DIV_4_STEP:
+ wMultiMotorStep = 4;
+ break;
+
+ case _32_TABLE_SPACE_FOR_1_DIV_8_STEP:
+ wMultiMotorStep = 8;
+ break;
+ }
+ wY *= wMultiMotorStep;
+
+ SetScanMode (chip, bScanBits);
+
+
+
+ /*set white shading int and dec */
+ if (chip->lsLightSource == LS_REFLECTIVE)
+ Mustek_SendData (chip, ES01_F8_WHITE_SHADING_DATA_FORMAT,
+ ES01_SHADING_3_INT_13_DEC);
+ else
+ Mustek_SendData (chip, ES01_F8_WHITE_SHADING_DATA_FORMAT,
+ ES01_SHADING_4_INT_12_DEC);
+
+ SetPackAddress (chip, wXResolution, wWidth, wX, XRatioAdderDouble,
+ XRatioTypeDouble, byClear_Pulse_Width, &ValidPixelNumber);
+ SetExtraSetting (chip, wXResolution, wCCD_PixelNumber, FALSE);
+
+ /* calculate line time */
+ byPHTG_PulseWidth = chip->Timing.PHTG_PluseWidth;
+ byPHTG_WaitWidth = chip->Timing.PHTG_WaitWidth;
+ dwLinePixelReport = ((byClear_Pulse_Width + 1) * 2 +
+ (byPHTG_PulseWidth + 1) * (1) +
+ (byPHTG_WaitWidth + 1) * (1) +
+ (wCCD_PixelNumber + 1)) * (byDummyCycleNum + 1);
+
+ DBG (DBG_ASIC, "Motor Time = %d\n",
+ (dwLinePixelReport * wYResolution / wNowMotorDPI) / wMultiMotorStep);
+ if ((dwLinePixelReport * wYResolution / wNowMotorDPI) / wMultiMotorStep >
+ 64000)
+ {
+ DBG (DBG_ASIC, "Motor Time Over Flow !!!\n");
+ }
+
+ EndSpeed =
+ (unsigned short) ((dwLinePixelReport * wYResolution / wNowMotorDPI) /
+ wMultiMotorStep);
+ SetMotorStepTable (chip, lpMotorStepsTable, wY, dwTotalLineTheBufferNeed * wNowMotorDPI / wYResolution * wMultiMotorStep, wYResolution); /*modified by Chester 92/04/08 */
+
+
+ if (EndSpeed >= 20000)
+ {
+ Asic_MotorMove (chip, 1, wY / wMultiMotorStep);
+ isUniformSpeedToScan = UNIFORM_MOTOR_AND_SCAN_SPEED_ENABLE;
+ isScanBackTracking = SCAN_BACK_TRACKING_DISABLE;
+ isMotorMoveToFirstLine = MOTOR_MOVE_TO_FIRST_LINE_DISABLE;
+ }
+
+ Mustek_SendData (chip, ES01_F3_ActionOption, isMotorMoveToFirstLine |
+ MOTOR_BACK_HOME_AFTER_SCAN_DISABLE |
+ SCAN_ENABLE |
+ isScanBackTracking |
+ INVERT_MOTOR_DIRECTION_DISABLE |
+ isUniformSpeedToScan |
+ ES01_STATIC_SCAN_DISABLE | MOTOR_TEST_LOOP_DISABLE);
+
+ if (EndSpeed > 8000)
+ {
+ StartSpeed = EndSpeed;
+ }
+ else
+ {
+ if (EndSpeed <= 1000)
+ StartSpeed = EndSpeed + 4500;
+ else
+ StartSpeed = EndSpeed + 3500;
+ }
+
+ Mustek_SendData (chip, ES01_FD_MotorFixedspeedLSB, LOBYTE (EndSpeed));
+ Mustek_SendData (chip, ES01_FE_MotorFixedspeedMSB, HIBYTE (EndSpeed));
+
+ lpMotorTable = (unsigned short *) malloc (512 * 8 * 2);
+ memset (lpMotorTable, 0, 512 * 8 * sizeof (unsigned short));
+
+ CalMotorTable.StartSpeed = StartSpeed;
+ CalMotorTable.EndSpeed = EndSpeed;
+ CalMotorTable.AccStepBeforeScan = lpMotorStepsTable->wScanAccSteps;
+ CalMotorTable.DecStepAfterScan = lpMotorStepsTable->bScanDecSteps;
+ CalMotorTable.lpMotorTable = lpMotorTable;
+
+ CalculateMotorTable (&CalMotorTable, wYResolution);
+
+ CurrentPhase.MotorDriverIs3967 = 0;
+ CurrentPhase.FillPhase = 1;
+ CurrentPhase.MoveType = bMotorMoveType;
+ SetMotorCurrent (chip, EndSpeed, &CurrentPhase);
+ LLFSetMotorCurrentAndPhase (chip, &CurrentPhase);
+
+ DBG (DBG_ASIC,
+ "EndSpeed = %d, BytesCountPerRow=%d, MotorCurrentTable=%d, LinePixelReport=%d\n",
+ EndSpeed, chip->dwBytesCountPerRow, CurrentPhase.MotorCurrentTableA[0],
+ dwLinePixelReport);
+
+ /* write motor table */
+ RealTableSize = 512 * 8;
+ dwTableBaseAddr = PackAreaStartAddress - RealTableSize;
+
+ dwStartAddr = dwTableBaseAddr;
+
+ RamAccess.ReadWrite = WRITE_RAM;
+ RamAccess.IsOnChipGamma = EXTERNAL_RAM;
+ RamAccess.DramDelayTime = SDRAMCLK_DELAY_12_ns;
+ RamAccess.LoStartAddress = (unsigned short) (dwStartAddr);
+ RamAccess.HiStartAddress = (unsigned short) (dwStartAddr >> 16);
+ RamAccess.RwSize = RealTableSize * 2;
+ RamAccess.BufferPtr = (SANE_Byte *) lpMotorTable;
+ LLFRamAccess (chip, &RamAccess);
+
+ Mustek_SendData (chip, ES01_DB_PH_RESET_EDGE_TIMING_ADJUST, 0x00);
+
+ Mustek_SendData (chip, ES01_DC_CLEAR_EDGE_TO_PH_TG_EDGE_WIDTH, 0);
+
+ Mustek_SendData (chip, ES01_9D_MotorTableAddrA14_A21,
+ (SANE_Byte) (dwTableBaseAddr >> TABLE_OFFSET_BASE));
+
+
+ /* set address and shading table */
+ /*set image buffer range and write shading table */
+ RealTableSize =
+ (ACC_DEC_STEP_TABLE_SIZE * NUM_OF_ACC_DEC_STEP_TABLE) +
+ ShadingTableSize (ValidPixelNumber);
+ dwShadingTableAddr =
+ PackAreaStartAddress -
+ (((RealTableSize +
+ (TABLE_BASE_SIZE - 1)) >> TABLE_OFFSET_BASE) << TABLE_OFFSET_BASE);
+ dwEndAddr = dwShadingTableAddr - 1;
+ dwStartAddr = dwShadingTableAddr;
+
+ if (wXResolution > 600)
+ dbXRatioAdderDouble = 1200 / wXResolution;
+ else
+ dbXRatioAdderDouble = 600 / wXResolution;
+
+ RamAccess.ReadWrite = WRITE_RAM;
+ RamAccess.IsOnChipGamma = EXTERNAL_RAM;
+ RamAccess.DramDelayTime = SDRAMCLK_DELAY_12_ns;
+ RamAccess.LoStartAddress = (unsigned short) (dwStartAddr);
+ RamAccess.HiStartAddress = (unsigned short) (dwStartAddr >> 16);
+ RamAccess.RwSize =
+ ShadingTableSize ((int) ((wWidth + 4) * dbXRatioAdderDouble)) *
+ sizeof (unsigned short);
+ RamAccess.BufferPtr = (SANE_Byte *) chip->lpShadingTable;
+ LLFRamAccess (chip, &RamAccess);
+
+ /*tell scan chip the shading table address, unit is 2^15 bytes(2^14 word) */
+ Mustek_SendData (chip, ES01_9B_ShadingTableAddrA14_A21,
+ (SANE_Byte) (dwShadingTableAddr >> TABLE_OFFSET_BASE));
+
+ /*empty bank */
+ Mustek_SendData (chip, ES01_FB_BufferEmptySize16WordLSB,
+ LOBYTE (WaitBufferOneLineSize >> (7 - 3)));
+ Mustek_SendData (chip, ES01_FC_BufferEmptySize16WordMSB,
+ HIBYTE (WaitBufferOneLineSize >> (7 - 3)));
+
+ /*full bank */
+ wFullBank =
+ (unsigned short) ((dwEndAddr -
+ (((dwLineWidthPixel * BytePerPixel) / 2) * 3 * 1)) / BANK_SIZE);
+ Mustek_SendData (chip, ES01_F9_BufferFullSize16WordLSB, LOBYTE (wFullBank));
+ Mustek_SendData (chip, ES01_FA_BufferFullSize16WordMSB, HIBYTE (wFullBank));
+
+
+ /* set buffer address */
+ LLFSetRamAddress (chip, 0x0, dwEndAddr, ACCESS_DRAM);
+
+ Mustek_SendData (chip, ES01_00_ADAFEConfiguration, 0x70);
+ Mustek_SendData (chip, ES01_02_ADAFEMuxConfig, 0x80);
+
+ free (lpMotorTable);
+ free (lpMotorStepsTable);
+ chip->firmwarestate = FS_OPENED;
+
+ DBG (DBG_ASIC, "Asic_SetWindow: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_Reset (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "Asic_Reset: Enter\n");
+
+ chip->lsLightSource = LS_REFLECTIVE;
+
+ chip->dwBytesCountPerRow = 0;
+ chip->AD.DirectionR = 0;
+ chip->AD.DirectionG = 0;
+ chip->AD.DirectionB = 0;
+ chip->AD.GainR = 0;
+ chip->AD.GainG = 0;
+ chip->AD.GainB = 0;
+
+ chip->AD.OffsetR = 0;
+ chip->AD.OffsetG = 0;
+ chip->AD.OffsetB = 0;
+
+ chip->Scan.TotalMotorSteps = 60000;
+ chip->Scan.StartLine = 0;
+ chip->Scan.StartPixel = 0;
+
+ DBG (DBG_ASIC, "Asic_Reset: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_SetSource (PAsic chip, LIGHTSOURCE lsLightSource)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "Asic_SetSource: Enter\n");
+
+ chip->lsLightSource = lsLightSource;
+ switch (chip->lsLightSource)
+ {
+ case 1:
+ DBG (DBG_ASIC, "Asic_SetSource: Source is Reflect\n");
+ break;
+ case 2:
+ DBG (DBG_ASIC, "Asic_SetSource: Source is Postion\n");
+ break;
+ case 4:
+ DBG (DBG_ASIC, "Asic_SetSource: Source is Negtive\n");
+ break;
+ default:
+ DBG (DBG_ASIC, "Asic_SetSource: Source error\n");
+ }
+
+ DBG (DBG_ASIC, "Asic_SetSource: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_ScanStart (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "Asic_ScanStart: Enter\n");
+
+ if (chip->firmwarestate != FS_OPENED)
+ {
+ DBG (DBG_ERR, "Asic_ScanStart: Scanner is not opened\n");
+ return STATUS_INVAL;
+ }
+
+ Mustek_SendData (chip, ES01_8B_Status, 0x1c | 0x20);
+ Mustek_WriteAddressLineForRegister (chip, 0x8B);
+ Mustek_ClearFIFO (chip);
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_ENABLE);
+
+
+ chip->firmwarestate = FS_SCANNING;
+
+ DBG (DBG_ASIC, "Asic_ScanStart: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_ScanStop (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte temps[2];
+ SANE_Byte buf[4];
+
+ DBG (DBG_ASIC, "Asic_ScanStop: Enter\n");
+
+ if (chip->firmwarestate < FS_SCANNING)
+ {
+ return status;
+ }
+
+ usleep (100 * 1000);
+
+ buf[0] = 0x02; /*stop */
+ buf[1] = 0x02;
+ buf[2] = 0x02;
+ buf[3] = 0x02;
+ status = WriteIOControl (chip, 0xc0, 0, 4, buf);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Asic_ScanStop: Stop scan error\n");
+ return status;
+ }
+
+ buf[0] = 0x00; /*clear */
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ buf[3] = 0x00;
+ status = WriteIOControl (chip, 0xc0, 0, 4, buf);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Asic_ScanStop: Clear scan error\n");
+ return status;
+ }
+
+ status = Mustek_DMARead (chip, 2, temps);
+ if (status != STATUS_GOOD)
+ {
+ DBG (DBG_ERR, "Asic_ScanStop: DMAReadGeneralMode error\n");
+ return status;
+ }
+
+ Mustek_SendData (chip, ES01_F3_ActionOption, 0);
+ Mustek_SendData (chip, ES01_86_DisableAllClockWhenIdle,
+ CLOSE_ALL_CLOCK_DISABLE);
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+ Mustek_ClearFIFO (chip);
+
+ chip->firmwarestate = FS_OPENED;
+ DBG (DBG_ASIC, "Asic_ScanStop: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_ReadImage (PAsic chip, SANE_Byte * pBuffer, unsigned short LinesCount)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned int dwXferBytes;
+
+ DBG (DBG_ASIC, "Asic_ReadImage: Enter : LinesCount = %d\n", LinesCount);
+
+ if (chip->firmwarestate != FS_SCANNING)
+ {
+ DBG (DBG_ERR, "Asic_ReadImage: Scanner is not scanning\n");
+ return STATUS_INVAL;
+ }
+
+ dwXferBytes = (unsigned int) (LinesCount) * chip->dwBytesCountPerRow;
+ DBG (DBG_ASIC, "Asic_ReadImage: chip->dwBytesCountPerRow = %d\n",
+ chip->dwBytesCountPerRow);
+
+ /* HOLD: an unsigned long can't be < 0
+ if (dwXferBytes < 0)
+ {
+ DBG (DBG_ASIC, "Asic_ReadImage: dwXferBytes <0\n");
+ return STATUS_INVAL;
+ }
+ */
+ if (dwXferBytes == 0)
+
+ {
+ DBG (DBG_ASIC, "Asic_ReadImage: dwXferBytes == 0\n");
+ return STATUS_GOOD;
+ }
+
+ status = Mustek_DMARead (chip, dwXferBytes, pBuffer);
+
+ DBG (DBG_ASIC, "Asic_ReadImage: Exit\n");
+ return status;
+}
+
+
+#if SANE_UNUSED
+static STATUS
+Asic_CheckFunctionKey (PAsic chip, SANE_Byte * key)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte bBuffer_1 = 0xff;
+ SANE_Byte bBuffer_2 = 0xff;
+
+ DBG (DBG_ASIC, "Asic_CheckFunctionKey: Enter\n");
+
+ if (chip->firmwarestate != FS_OPENED)
+ {
+ DBG (DBG_ERR, "Asic_CheckFunctionKey: Scanner is not Opened\n");
+ return STATUS_INVAL;
+ }
+
+ Mustek_SendData (chip, ES01_97_GPIOControl0_7, 0x00);
+ Mustek_SendData (chip, ES01_95_GPIOValue0_7, 0x17);
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x00);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x08);
+
+ GetChipStatus (chip, 0x02, &bBuffer_1);
+ GetChipStatus (chip, 0x03, &bBuffer_2);
+
+
+ if (((0xff - bBuffer_1) & 0x10) == 0x10)
+ *key = 0x01;
+
+ if (((0xff - bBuffer_1) & 0x01) == 0x01)
+ *key = 0x02;
+ if (((0xff - bBuffer_1) & 0x04) == 0x04)
+ *key = 0x04;
+ if (((0xff - bBuffer_2) & 0x08) == 0x08)
+ *key = 0x08;
+ if (((0xff - bBuffer_1) & 0x02) == 0x02)
+ *key = 0x10;
+
+
+ DBG (DBG_ASIC, "CheckFunctionKey=%d\n", *key);
+ DBG (DBG_ASIC, "Asic_CheckFunctionKey: Exit\n");
+ return status;
+}
+#endif
+
+static STATUS
+Asic_IsTAConnected (PAsic chip, SANE_Bool * hasTA)
+{
+ SANE_Byte bBuffer_1 = 0xff;
+
+ DBG (DBG_ASIC, "Asic_IsTAConnected: Enter\n");
+
+ Mustek_SendData (chip, ES01_97_GPIOControl0_7, 0x00);
+ Mustek_SendData (chip, ES01_95_GPIOValue0_7, 0x00);
+
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x00);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x00);
+
+
+ GetChipStatus (chip, 0x02, &bBuffer_1);
+
+ if (((0xff - bBuffer_1) & 0x08) == 0x08)
+ *hasTA = TRUE;
+ else
+ *hasTA = FALSE;
+
+ DBG (DBG_ASIC, "hasTA=%d\n", *hasTA);
+ DBG (DBG_ASIC, "Asic_IsTAConnected():Exit\n");
+ return STATUS_GOOD;
+}
+
+#if SANE_UNUSED
+static STATUS
+Asic_DownloadGammaTable (PAsic chip, void * lpBuffer)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "Asic_DownloadGammaTable()\n");
+
+ chip->lpGammaTable = lpBuffer;
+
+ DBG (DBG_ASIC, "Asic_DownloadGammaTable: Exit\n");
+ return status;
+}
+#endif
+
+static STATUS
+Asic_ReadCalibrationData (PAsic chip, void * pBuffer,
+ unsigned int dwXferBytes, SANE_Byte bScanBits)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Byte * pCalBuffer;
+ unsigned int dwTotalReadData;
+ unsigned int dwReadImageData;
+
+ DBG (DBG_ASIC, "Asic_ReadCalibrationData: Enter\n");
+
+ if (chip->firmwarestate != FS_SCANNING)
+ {
+ DBG (DBG_ERR, "Asic_ReadCalibrationData: Scanner is not scanning\n");
+ return STATUS_INVAL;
+ }
+
+ if (bScanBits == 24)
+ {
+ unsigned int i;
+ pCalBuffer = (SANE_Byte *) malloc (dwXferBytes);
+ if (pCalBuffer == NULL)
+ {
+ DBG (DBG_ERR,
+ "Asic_ReadCalibrationData: Can't malloc bCalBuffer memory\n");
+ return STATUS_MEM_ERROR;
+ }
+
+ for (dwTotalReadData = 0; dwTotalReadData < dwXferBytes;)
+ {
+ dwReadImageData = (dwXferBytes - dwTotalReadData) < 65536 ?
+ (dwXferBytes - dwTotalReadData) : 65536;
+
+ Mustek_DMARead (chip, dwReadImageData,
+ (SANE_Byte *) (pCalBuffer + dwTotalReadData));
+ dwTotalReadData += dwReadImageData;
+ }
+
+ dwXferBytes /= 3;
+ for (i = 0; i < dwXferBytes; i++)
+
+ {
+ *((SANE_Byte *) pBuffer + i) = *(pCalBuffer + i * 3);
+ *((SANE_Byte *) pBuffer + dwXferBytes + i) = *(pCalBuffer + i * 3 + 1);
+ *((SANE_Byte *) pBuffer + dwXferBytes * 2 + i) =
+ *(pCalBuffer + i * 3 + 2);
+ }
+ free (pCalBuffer);
+ }
+ else if (bScanBits == 8)
+ {
+ for (dwTotalReadData = 0; dwTotalReadData < dwXferBytes;)
+ {
+ dwReadImageData = (dwXferBytes - dwTotalReadData) < 65536 ?
+ (dwXferBytes - dwTotalReadData) : 65536;
+
+ Mustek_DMARead (chip, dwReadImageData,
+ (SANE_Byte *) pBuffer + dwTotalReadData);
+ dwTotalReadData += dwReadImageData;
+ }
+ }
+
+ DBG (DBG_ASIC, "Asic_ReadCalibrationData: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_SetMotorType (PAsic chip, SANE_Bool isMotorMove, SANE_Bool isUniformSpeed)
+{
+ STATUS status = STATUS_GOOD;
+ isUniformSpeed = isUniformSpeed;
+ DBG (DBG_ASIC, "Asic_SetMotorType:Enter\n");
+
+ if (isMotorMove)
+ {
+ chip->isMotorMove = MOTOR_0_ENABLE;
+ }
+ else
+ chip->isMotorMove = MOTOR_0_DISABLE;
+
+ DBG (DBG_ASIC, "isMotorMove=%d\n", chip->isMotorMove);
+ DBG (DBG_ASIC, "Asic_SetMotorType: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_MotorMove (PAsic chip, SANE_Bool isForward, unsigned int dwTotalSteps)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned short *NormalMoveMotorTable;
+ LLF_CALCULATEMOTORTABLE CalMotorTable;
+ LLF_MOTOR_CURRENT_AND_PHASE CurrentPhase;
+ LLF_SETMOTORTABLE LLF_SetMotorTable;
+ LLF_MOTORMOVE MotorMove;
+
+ DBG (DBG_ASIC, "Asic_MotorMove:Enter\n");
+
+ NormalMoveMotorTable = (unsigned short *) malloc (512 * 8 * 2);
+
+ CalMotorTable.StartSpeed = 5000;
+ CalMotorTable.EndSpeed = 1800;
+ CalMotorTable.AccStepBeforeScan = 511;
+ CalMotorTable.lpMotorTable = NormalMoveMotorTable;
+ LLFCalculateMotorTable (&CalMotorTable);
+
+ CurrentPhase.MotorDriverIs3967 = 0;
+ CurrentPhase.MotorCurrentTableA[0] = 200;
+ CurrentPhase.MotorCurrentTableB[0] = 200;
+ CurrentPhase.MoveType = _4_TABLE_SPACE_FOR_FULL_STEP;
+ LLFSetMotorCurrentAndPhase (chip, &CurrentPhase);
+
+ LLF_SetMotorTable.MotorTableAddress = 0;
+ LLF_SetMotorTable.MotorTablePtr = NormalMoveMotorTable;
+ LLFSetMotorTable (chip, &LLF_SetMotorTable);
+
+ free (NormalMoveMotorTable);
+
+ MotorMove.MotorSelect = MOTOR_0_ENABLE | MOTOR_1_DISABLE;
+ MotorMove.MotorMoveUnit = ES03_TABLE_DEFINE;
+ MotorMove.MotorSpeedUnit = SPEED_UNIT_1_PIXEL_TIME;
+ MotorMove.MotorSyncUnit = MOTOR_SYNC_UNIT_1_PIXEL_TIME;
+ MotorMove.HomeSensorSelect = HOME_SENSOR_0_ENABLE;
+ MotorMove.ActionMode = ACTION_MODE_ACCDEC_MOVE;
+ MotorMove.ActionType = isForward;
+
+ if (dwTotalSteps > 1000)
+ {
+ MotorMove.AccStep = 511;
+ MotorMove.DecStep = 255;
+ MotorMove.FixMoveSteps = dwTotalSteps - (511 + 255);
+ }
+ else
+ {
+
+ MotorMove.ActionMode = ACTION_MODE_UNIFORM_SPEED_MOVE;
+ MotorMove.AccStep = 1;
+ MotorMove.DecStep = 1;
+ MotorMove.FixMoveSteps = dwTotalSteps - 2;
+ }
+
+ MotorMove.FixMoveSpeed = 7000;
+ MotorMove.WaitOrNoWait = TRUE;
+
+ LLFMotorMove (chip, &MotorMove);
+
+ DBG (DBG_ASIC, "Asic_MotorMove: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_CarriageHome (PAsic chip, SANE_Bool isTA)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Bool LampHome, TAHome;
+ isTA = isTA;
+
+ DBG (DBG_ASIC, "Asic_CarriageHome:Enter\n");
+
+ status = IsCarriageHome (chip, &LampHome, &TAHome);
+ if (!LampHome)
+ {
+ status = MotorBackHome (chip, TRUE);
+ }
+
+ DBG (DBG_ASIC, "Asic_CarriageHome: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_SetShadingTable (PAsic chip, unsigned short * lpWhiteShading,
+ unsigned short * lpDarkShading,
+ unsigned short wXResolution, unsigned short wWidth, unsigned short wX)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned short i, j, n;
+ unsigned short wValidPixelNumber;
+ double dbXRatioAdderDouble;
+ unsigned int wShadingTableSize;
+
+ wX = wX;
+ DBG (DBG_ASIC, "Asic_SetShadingTable:Enter\n");
+
+ if (chip->firmwarestate < FS_OPENED)
+
+ OpenScanChip (chip);
+ if (chip->firmwarestate == FS_SCANNING)
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+
+
+ if (wXResolution > 600)
+ dbXRatioAdderDouble = 1200 / wXResolution;
+ else
+ dbXRatioAdderDouble = 600 / wXResolution;
+
+ wValidPixelNumber = (unsigned short) ((wWidth + 4) * dbXRatioAdderDouble);
+ DBG (DBG_ASIC, "wValidPixelNumber = %d\n", wValidPixelNumber);
+
+ /* clear old Shading table, if it has. */
+ /* first 4 element and lastest 5 of Shading table can't been used */
+ wShadingTableSize = (ShadingTableSize (wValidPixelNumber)) * sizeof (unsigned short);
+ if (chip->lpShadingTable != NULL)
+ {
+ free (chip->lpShadingTable);
+
+ }
+
+ DBG (DBG_ASIC, "Alloc a new shading table= %d Byte!\n", wShadingTableSize);
+ chip->lpShadingTable = (SANE_Byte *) malloc (wShadingTableSize);
+ if (chip->lpShadingTable == NULL)
+ {
+ DBG (DBG_ASIC, "lpShadingTable == NULL\n");
+ return STATUS_MEM_ERROR;
+ }
+
+ n = 0;
+ for (i = 0; i <= (wValidPixelNumber / 40); i++)
+ {
+ if (i < (wValidPixelNumber / 40))
+ {
+ for (j = 0; j < 40; j++)
+ {
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6) =
+ *((unsigned short *) lpDarkShading + n * 3);
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 2) =
+ *((unsigned short *) lpDarkShading + n * 3 + 1);
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 4) =
+ *((unsigned short *) lpDarkShading + n * 3 + 2);
+
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 1) =
+ *((unsigned short *) lpWhiteShading + n * 3);
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 3) =
+ *((unsigned short *) lpWhiteShading + n * 3 + 1);
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 5) =
+ *((unsigned short *) lpWhiteShading + n * 3 + 2);
+ if ((j % (unsigned short) dbXRatioAdderDouble) ==
+ (dbXRatioAdderDouble - 1))
+ n++;
+
+ if (i == 0 && j < 4 * dbXRatioAdderDouble)
+ n = 0;
+ }
+ }
+ else
+ {
+ for (j = 0; j < (wValidPixelNumber % 40); j++)
+ {
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6) =
+ *((unsigned short *) lpDarkShading + (n) * 3);
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 2) =
+ *((unsigned short *) lpDarkShading + (n) * 3 + 1);
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 4) =
+ *((unsigned short *) lpDarkShading + (n) * 3 + 2);
+
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 1) =
+ *((unsigned short *) lpWhiteShading + (n) * 3);
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 3) =
+ *((unsigned short *) lpWhiteShading + (n) * 3 + 1);
+ *((unsigned short *) chip->lpShadingTable + i * 256 + j * 6 + 5) =
+ *((unsigned short *) lpWhiteShading + (n) * 3 + 2);
+
+ if ((j % (unsigned short) dbXRatioAdderDouble) ==
+ (dbXRatioAdderDouble - 1))
+ n++;
+
+ if (i == 0 && j < 4 * dbXRatioAdderDouble)
+ n = 0;
+ }
+ }
+ }
+
+ DBG (DBG_ASIC, "Asic_SetShadingTable: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_WaitCarriageHome (PAsic chip, SANE_Bool isTA)
+{
+ STATUS status = STATUS_GOOD;
+ SANE_Bool LampHome, TAHome;
+ int i;
+
+ isTA = isTA;
+
+ DBG (DBG_ASIC, "Asic_WaitCarriageHome:Enter\n");
+
+ for (i = 0; i < 100; i++)
+ {
+ status = IsCarriageHome (chip, &LampHome, &TAHome);
+ if (LampHome)
+ break;
+ usleep (300000);
+ }
+ if (i == 100)
+ status = STATUS_DEVICE_BUSY;
+ DBG (DBG_ASIC, "Wait %d s\n", (unsigned short) (i * 0.3));
+
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+ chip->firmwarestate = FS_OPENED;
+ chip->motorstate = MS_STILL;
+
+ DBG (DBG_ASIC, "Asic_WaitCarriageHome: Exit\n");
+ return status;
+}
+
+static STATUS
+Asic_SetCalibrate (PAsic chip, SANE_Byte bScanBits, unsigned short wXResolution,
+ unsigned short wYResolution, unsigned short wX, unsigned short wY,
+ unsigned short wWidth, unsigned short wLength, SANE_Bool isShading)
+{
+ STATUS status = STATUS_GOOD;
+ unsigned short ValidPixelNumber;
+
+ unsigned short wPerLineNeedBufferSize = 0;
+ unsigned short BytePerPixel = 0;
+ unsigned int dwTotal_PerLineNeedBufferSize = 0;
+ unsigned int dwTotalLineTheBufferNeed = 0;
+ unsigned short dwTotal_CCDResolution = 0;
+ unsigned short wThinkCCDResolution = 0;
+ unsigned short wCCD_PixelNumber = 0;
+ unsigned short wScanAccSteps = 1;
+ SANE_Byte byScanDecSteps = 1;
+ unsigned int dwLineWidthPixel = 0;
+
+ unsigned short wNowMotorDPI;
+ unsigned short XRatioTypeWord;
+ double XRatioTypeDouble;
+ double XRatioAdderDouble;
+
+ LLF_MOTORMOVE *lpMotorStepsTable =
+ (LLF_MOTORMOVE *) malloc (sizeof (LLF_MOTORMOVE));
+
+ SANE_Byte byDummyCycleNum = 1;
+ unsigned short Total_MotorDPI;
+ unsigned short BeforeScanFixSpeedStep = 0;
+ unsigned short BackTrackFixSpeedStep = 20;
+ unsigned short wMultiMotorStep = 1;
+ SANE_Byte bMotorMoveType = _MOTOR_MOVE_TYPE;
+ SANE_Byte isMotorMoveToFirstLine = MOTOR_MOVE_TO_FIRST_LINE_DISABLE;
+ SANE_Byte isUniformSpeedToScan = UNIFORM_MOTOR_AND_SCAN_SPEED_ENABLE;
+ SANE_Byte isScanBackTracking = SCAN_BACK_TRACKING_DISABLE;
+ unsigned int TotalStep = 0;
+ unsigned short StartSpeed, EndSpeed;
+ LLF_CALCULATEMOTORTABLE CalMotorTable;
+ LLF_MOTOR_CURRENT_AND_PHASE CurrentPhase;
+ LLF_RAMACCESS RamAccess;
+ unsigned int dwStartAddr, dwEndAddr, dwTableBaseAddr;
+ SANE_Byte byClear_Pulse_Width = 0;
+ unsigned int dwLinePixelReport = 0;
+ SANE_Byte byPHTG_PulseWidth, byPHTG_WaitWidth;
+ unsigned short * lpMotorTable = (unsigned short *) malloc (512 * 8 * 2);
+ unsigned int RealTableSize;
+ unsigned short wFullBank;
+
+ DBG (DBG_ASIC, "Asic_SetCalibrate: Enter\n");
+ DBG (DBG_ASIC,
+ "bScanBits=%d,wXResolution=%d, wYResolution=%d, wX=%d, wY=%d, wWidth=%d, wLength=%d\n",
+ bScanBits, wXResolution, wYResolution, wX, wY, wWidth, wLength);
+
+ if (chip->firmwarestate != FS_OPENED)
+ {
+ DBG (DBG_ERR, "Asic_SetCalibrate: Scanner is not opened\n");
+ return STATUS_INVAL;
+ }
+
+ if (lpMotorStepsTable == NULL)
+ {
+ DBG (DBG_ERR, "Asic_SetCalibrate: insufficiency memory!\n");
+ return STATUS_INVAL;
+ }
+ DBG (DBG_ASIC, "malloc LLF_MOTORMOVE =%ld Byte\n", (long int) (sizeof (LLF_MOTORMOVE)));
+
+ Mustek_SendData (chip, ES01_F3_ActionOption, 0);
+ Mustek_SendData (chip, ES01_86_DisableAllClockWhenIdle,
+ CLOSE_ALL_CLOCK_DISABLE);
+ Mustek_SendData (chip, ES01_F4_ActiveTriger, ACTION_TRIGER_DISABLE);
+
+ status = Asic_WaitUnitReady (chip);
+
+ Mustek_SendData (chip, 0x1CD, 0);
+
+ Mustek_SendData (chip, ES01_94_PowerSaveControl, 0x27 | 64 | 128);
+
+ if (bScanBits > 24)
+ {
+ wPerLineNeedBufferSize = wWidth * 6;
+ BytePerPixel = 6;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth) * 6;
+ }
+ else if (bScanBits == 24)
+ {
+ wPerLineNeedBufferSize = wWidth * 3;
+ chip->dwCalibrationBytesCountPerRow = wWidth * 3;
+ BytePerPixel = 3;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth) * 3;
+ }
+ else if ((bScanBits > 8) && (bScanBits <= 16))
+ {
+ wPerLineNeedBufferSize = wWidth * 2;
+ BytePerPixel = 2;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth) * 2;
+ }
+ else if ((bScanBits == 8))
+ {
+ wPerLineNeedBufferSize = wWidth;
+ BytePerPixel = 1;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth);
+ }
+ else if ((bScanBits < 8))
+ {
+ wPerLineNeedBufferSize = wWidth >> 3;
+ BytePerPixel = 1;
+ chip->dwBytesCountPerRow = (unsigned int) (wWidth);
+ }
+ DBG (DBG_ASIC,
+ "wPerLineNeedBufferSize=%d,BytePerPixel=%d,dwBytesCountPerRow=%d\n",
+ wPerLineNeedBufferSize, BytePerPixel, chip->dwBytesCountPerRow);
+
+
+ dwTotal_PerLineNeedBufferSize = wPerLineNeedBufferSize;
+ dwTotalLineTheBufferNeed = wLength;
+ DBG (DBG_ASIC, "wPerLineNeedBufferSize=%d,wLength=%d\n",
+ wPerLineNeedBufferSize, wLength);
+
+
+ chip->Scan.Dpi = wXResolution;
+ CCDTiming (chip);
+
+ dwTotal_CCDResolution = SENSOR_DPI;
+ if (chip->lsLightSource == LS_REFLECTIVE)
+ {
+ if (wXResolution > (dwTotal_CCDResolution / 2))
+ {
+ wThinkCCDResolution = dwTotal_CCDResolution;
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x01);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x01);
+ wCCD_PixelNumber = chip->Timing.wCCDPixelNumber_1200;
+ }
+ else
+ {
+ wThinkCCDResolution = dwTotal_CCDResolution / 2;
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x01);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x00);
+ wCCD_PixelNumber = chip->Timing.wCCDPixelNumber_600;
+ }
+ }
+ else
+ {
+ if (wXResolution > (dwTotal_CCDResolution / 2))
+ {
+ wThinkCCDResolution = dwTotal_CCDResolution;
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x01);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x01);
+ wCCD_PixelNumber = TA_CAL_PIXELNUMBER;
+ }
+ else
+ {
+ wThinkCCDResolution = dwTotal_CCDResolution / 2;
+ Mustek_SendData (chip, ES01_98_GPIOControl8_15, 0x01);
+ Mustek_SendData (chip, ES01_96_GPIOValue8_15, 0x00);
+ wCCD_PixelNumber = TA_CAL_PIXELNUMBER;
+ }
+ }
+ DBG (DBG_ASIC, "wThinkCCDResolution=%d,wCCD_PixelNumber=%d\n",
+ wThinkCCDResolution, wCCD_PixelNumber);
+
+ dwLineWidthPixel = wWidth;
+
+ if (isShading)
+ wYResolution = 600;
+ DBG (DBG_ASIC, "dwLineWidthPixel=%d,wYResolution=%d\n", dwLineWidthPixel,
+ wYResolution);
+
+ SetLineTimeAndExposure (chip);
+ if (wYResolution == 600)
+ {
+ Mustek_SendData (chip, ES01_CB_CCDDummyCycleNumber, byDummyCycleNum);
+ DBG (DBG_ASIC, "Find Boundary CCDDummyCycleNumber == %d\n",
+ byDummyCycleNum);
+ }
+
+ SetLEDTime (chip);
+
+ /* calculate Y ratio */
+ Total_MotorDPI = 1200;
+
+ wNowMotorDPI = Total_MotorDPI;
+ DBG (DBG_ASIC, "wNowMotorDPI=%d\n", wNowMotorDPI);
+
+ /* SetADConverter */
+ Mustek_SendData (chip, ES01_74_HARDWARE_SETTING,
+ MOTOR1_SERIAL_INTERFACE_G10_8_ENABLE | LED_OUT_G11_DISABLE
+ | SLAVE_SERIAL_INTERFACE_G15_14_DISABLE |
+ SHUTTLE_CCD_DISABLE);
+
+ /* set AFE */
+ Mustek_SendData (chip, ES01_9A_AFEControl,
+ AD9826_AFE | AUTO_CHANGE_AFE_GAIN_OFFSET_DISABLE);
+ Mustek_SendData (chip, ES01_F7_DigitalControl, DIGITAL_REDUCE_DISABLE);
+
+ XRatioTypeDouble = wXResolution;
+ XRatioTypeDouble /= wThinkCCDResolution;
+ XRatioAdderDouble = 1 / XRatioTypeDouble;
+ XRatioTypeWord = (unsigned short) (XRatioTypeDouble * 32768);
+
+ XRatioAdderDouble = (double) (XRatioTypeWord) / 32768;
+ XRatioAdderDouble = 1 / XRatioAdderDouble;
+
+ Mustek_SendData (chip, ES01_9E_HorizontalRatio1to15LSB,
+ LOBYTE (XRatioTypeWord));
+ Mustek_SendData (chip, ES01_9F_HorizontalRatio1to15MSB,
+ HIBYTE (XRatioTypeWord));
+ DBG (DBG_ASIC,
+ "XRatioTypeDouble=%.2f,XRatioAdderDouble=%.2f,XRatioTypeWord=%d\n",
+ XRatioTypeDouble, XRatioAdderDouble, XRatioTypeWord);
+
+ if (chip->isMotorMove == MOTOR_0_ENABLE)
+ {
+ Mustek_SendData (chip, ES01_A6_MotorOption, MOTOR_0_ENABLE |
+ MOTOR_1_DISABLE |
+ HOME_SENSOR_0_ENABLE | ES03_TABLE_DEFINE);
+ }
+ else
+ {
+ Mustek_SendData (chip, ES01_A6_MotorOption, MOTOR_0_DISABLE |
+ MOTOR_1_DISABLE |
+ HOME_SENSOR_0_ENABLE | ES03_TABLE_DEFINE);
+ }
+ DBG (DBG_ASIC, "isMotorMove=%d\n", chip->isMotorMove);
+
+ Mustek_SendData (chip, ES01_F6_MorotControl1, SPEED_UNIT_1_PIXEL_TIME |
+ MOTOR_SYNC_UNIT_1_PIXEL_TIME);
+
+ wScanAccSteps = 1;
+ byScanDecSteps = 1;
+ DBG (DBG_ASIC, "wScanAccSteps=%d,byScanDecSteps=%d\n", wScanAccSteps,
+ byScanDecSteps);
+
+ Mustek_SendData (chip, ES01_AE_MotorSyncPixelNumberM16LSB, LOBYTE (0));
+ Mustek_SendData (chip, ES01_AF_MotorSyncPixelNumberM16MSB, HIBYTE (0));
+ DBG (DBG_ASIC, "MotorSyncPixelNumber=%d\n", 0);
+
+ Mustek_SendData (chip, ES01_EC_ScanAccStep0_7, LOBYTE (wScanAccSteps));
+ Mustek_SendData (chip, ES01_ED_ScanAccStep8_8, HIBYTE (wScanAccSteps));
+ DBG (DBG_ASIC, "wScanAccSteps=%d\n", wScanAccSteps);
+
+ DBG (DBG_ASIC, "BeforeScanFixSpeedStep=%d,BackTrackFixSpeedStep=%d\n",
+ BeforeScanFixSpeedStep, BackTrackFixSpeedStep);
+
+ Mustek_SendData (chip, ES01_EE_FixScanStepLSB,
+ LOBYTE (BeforeScanFixSpeedStep));
+ Mustek_SendData (chip, ES01_8A_FixScanStepMSB,
+ HIBYTE (BeforeScanFixSpeedStep));
+ DBG (DBG_ASIC, "BeforeScanFixSpeedStep=%d\n", BeforeScanFixSpeedStep);
+
+ Mustek_SendData (chip, ES01_EF_ScanDecStep, byScanDecSteps);
+ DBG (DBG_ASIC, "byScanDecSteps=%d\n", byScanDecSteps);
+
+ Mustek_SendData (chip, ES01_E6_ScanBackTrackingStepLSB,
+ LOBYTE (BackTrackFixSpeedStep));
+ Mustek_SendData (chip, ES01_E7_ScanBackTrackingStepMSB,
+ HIBYTE (BackTrackFixSpeedStep));
+ DBG (DBG_ASIC, "BackTrackFixSpeedStep=%d\n", BackTrackFixSpeedStep);
+
+ Mustek_SendData (chip, ES01_E8_ScanRestartStepLSB,
+ LOBYTE (BackTrackFixSpeedStep));
+ Mustek_SendData (chip, ES01_E9_ScanRestartStepMSB,
+ HIBYTE (BackTrackFixSpeedStep));
+ DBG (DBG_ASIC, "BackTrackFixSpeedStep=%d\n", BackTrackFixSpeedStep);
+
+ switch (bMotorMoveType)
+ {
+ case _4_TABLE_SPACE_FOR_FULL_STEP:
+ wMultiMotorStep = 1;
+ break;
+
+ case _8_TABLE_SPACE_FOR_1_DIV_2_STEP:
+ wMultiMotorStep = 2;
+ break;
+
+ case _16_TABLE_SPACE_FOR_1_DIV_4_STEP:
+ wMultiMotorStep = 4;
+ break;
+
+ case _32_TABLE_SPACE_FOR_1_DIV_8_STEP:
+ wMultiMotorStep = 8;
+ break;
+ }
+ DBG (DBG_ASIC, "wMultiMotorStep=%d\n", wMultiMotorStep);
+
+ TotalStep = wScanAccSteps + BeforeScanFixSpeedStep +
+ (dwTotalLineTheBufferNeed * wNowMotorDPI / wYResolution) + byScanDecSteps;
+ DBG (DBG_ASIC, "TotalStep=%d\n", TotalStep);
+
+ Mustek_SendData (chip, ES01_F0_ScanImageStep0_7, (SANE_Byte) (TotalStep));
+ Mustek_SendData (chip, ES01_F1_ScanImageStep8_15, (SANE_Byte) (TotalStep >> 8));
+ Mustek_SendData (chip, ES01_F2_ScanImageStep16_19,
+ (SANE_Byte) (TotalStep >> 16));
+
+ SetScanMode (chip, bScanBits);
+
+ DBG (DBG_ASIC,
+ "isMotorMoveToFirstLine=%d,isUniformSpeedToScan=%d,isScanBackTracking=%d\n",
+ isMotorMoveToFirstLine, isUniformSpeedToScan, isScanBackTracking);
+
+
+ Mustek_SendData (chip, ES01_F3_ActionOption, isMotorMoveToFirstLine |
+ MOTOR_BACK_HOME_AFTER_SCAN_DISABLE |
+ SCAN_ENABLE |
+ isScanBackTracking |
+ INVERT_MOTOR_DIRECTION_DISABLE |
+ isUniformSpeedToScan |
+ ES01_STATIC_SCAN_DISABLE | MOTOR_TEST_LOOP_DISABLE);
+
+ if (chip->lsLightSource == LS_REFLECTIVE)
+ Mustek_SendData (chip, ES01_F8_WHITE_SHADING_DATA_FORMAT,
+ ES01_SHADING_3_INT_13_DEC);
+ else
+ Mustek_SendData (chip, ES01_F8_WHITE_SHADING_DATA_FORMAT,
+ ES01_SHADING_4_INT_12_DEC);
+
+ SetPackAddress (chip, wXResolution, wWidth, wX, XRatioAdderDouble,
+ XRatioTypeDouble, byClear_Pulse_Width, &ValidPixelNumber);
+ SetExtraSetting (chip, wXResolution, wCCD_PixelNumber, TRUE);
+
+ byPHTG_PulseWidth = chip->Timing.PHTG_PluseWidth;
+ byPHTG_WaitWidth = chip->Timing.PHTG_WaitWidth;
+ dwLinePixelReport = ((byClear_Pulse_Width + 1) * 2 +
+ (byPHTG_PulseWidth + 1) * (1) +
+ (byPHTG_WaitWidth + 1) * (1) +
+ (wCCD_PixelNumber + 1)) * (byDummyCycleNum + 1);
+
+ DBG (DBG_ASIC, "Motor Time = %d\n",
+ (dwLinePixelReport * wYResolution / wNowMotorDPI));
+ if ((dwLinePixelReport * wYResolution / wNowMotorDPI) > 64000)
+ {
+ DBG (DBG_ASIC, "Motor Time Over Flow !!!\n");
+ }
+
+ EndSpeed = (unsigned short) (dwLinePixelReport / (wNowMotorDPI / wYResolution));
+
+ if (wXResolution > 600)
+ {
+ StartSpeed = EndSpeed;
+ }
+ else
+ {
+ StartSpeed = EndSpeed + 3500;
+ }
+ DBG (DBG_ASIC, "StartSpeed =%d, EndSpeed = %d\n", StartSpeed, EndSpeed);
+
+
+ Mustek_SendData (chip, ES01_FD_MotorFixedspeedLSB, LOBYTE (EndSpeed));
+ Mustek_SendData (chip, ES01_FE_MotorFixedspeedMSB, HIBYTE (EndSpeed));
+ memset (lpMotorTable, 0, 512 * 8 * sizeof (unsigned short));
+
+ CalMotorTable.StartSpeed = StartSpeed;
+ CalMotorTable.EndSpeed = EndSpeed;
+ CalMotorTable.AccStepBeforeScan = wScanAccSteps;
+ CalMotorTable.lpMotorTable = lpMotorTable;
+
+ LLFCalculateMotorTable (&CalMotorTable);
+
+ CurrentPhase.MotorDriverIs3967 = 0;
+ CurrentPhase.FillPhase = 1;
+ CurrentPhase.MoveType = bMotorMoveType;
+ CurrentPhase.MotorCurrentTableA[0] = 200;
+ CurrentPhase.MotorCurrentTableB[0] = 200;
+ LLFSetMotorCurrentAndPhase (chip, &CurrentPhase);
+
+ RealTableSize = 512 * 8;
+ dwTableBaseAddr = PackAreaStartAddress - RealTableSize;
+
+ dwStartAddr = dwTableBaseAddr;
+
+ RamAccess.ReadWrite = WRITE_RAM;
+ RamAccess.IsOnChipGamma = EXTERNAL_RAM;
+ RamAccess.DramDelayTime = SDRAMCLK_DELAY_12_ns;
+ RamAccess.LoStartAddress = (unsigned short) (dwStartAddr);
+ RamAccess.HiStartAddress = (unsigned short) (dwStartAddr >> 16);
+ RamAccess.RwSize = RealTableSize * 2;
+ RamAccess.BufferPtr = (SANE_Byte *) lpMotorTable;
+ LLFRamAccess (chip, &RamAccess);
+
+ Mustek_SendData (chip, ES01_9D_MotorTableAddrA14_A21,
+ (SANE_Byte) (dwTableBaseAddr >> TABLE_OFFSET_BASE));
+
+ dwEndAddr = PackAreaStartAddress - (512 * 8) - 1;
+
+ Mustek_SendData (chip, ES01_FB_BufferEmptySize16WordLSB,
+ LOBYTE (WaitBufferOneLineSize >> (7 - 3)));
+ Mustek_SendData (chip, ES01_FC_BufferEmptySize16WordMSB,
+ HIBYTE (WaitBufferOneLineSize >> (7 - 3)));
+
+ wFullBank =
+ (unsigned short) ((dwEndAddr -
+ (((dwLineWidthPixel * BytePerPixel) / 2) * 3 * 1)) / BANK_SIZE);
+ Mustek_SendData (chip, ES01_F9_BufferFullSize16WordLSB, LOBYTE (wFullBank));
+ Mustek_SendData (chip, ES01_FA_BufferFullSize16WordMSB, HIBYTE (wFullBank));
+
+ Mustek_SendData (chip, ES01_DB_PH_RESET_EDGE_TIMING_ADJUST, 0x00);
+
+ LLFSetRamAddress (chip, 0x0, dwEndAddr, ACCESS_DRAM);
+
+ Mustek_SendData (chip, ES01_DC_CLEAR_EDGE_TO_PH_TG_EDGE_WIDTH, 0);
+
+ Mustek_SendData (chip, ES01_00_ADAFEConfiguration, 0x70);
+ Mustek_SendData (chip, ES01_02_ADAFEMuxConfig, 0x80);
+
+
+ free (lpMotorTable);
+ free (lpMotorStepsTable);
+
+ DBG (DBG_ASIC, "Asic_SetCalibrate: Exit\n");
+ return status;
+}
+
+
+static STATUS
+Asic_SetAFEGainOffset (PAsic chip)
+{
+ STATUS status = STATUS_GOOD;
+ DBG (DBG_ASIC, "Asic_SetAFEGainOffset:Enter\n");
+
+ status = SetAFEGainOffset (chip);
+
+ DBG (DBG_ASIC, "Asic_SetAFEGainOffset: Exit\n");
+ return status;
+}