1 /* @file u12-motor.c
2 * @brief all functions for motor control
3 *
4 * based on sources acquired from Plustek Inc.
5 * Copyright (C) 2003-2004 Gerhard Jaeger <gerhard@gjaeger.de>
6 *
7 * History:
8 * - 0.01 - initial version
9 * - 0.02 - no changes
10 * .
11 * <hr>
12 * This file is part of the SANE package.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26 *
27 * As a special exception, the authors of SANE give permission for
28 * additional uses of the libraries contained in this release of SANE.
29 *
30 * The exception is that, if you link a SANE library with other files
31 * to produce an executable, this does not by itself cause the
32 * resulting executable to be covered by the GNU General Public
33 * License. Your use of that executable is in no way restricted on
34 * account of linking the SANE library code into it.
35 *
36 * This exception does not, however, invalidate any other reasons why
37 * the executable file might be covered by the GNU General Public
38 * License.
39 *
40 * If you submit changes to SANE to the maintainers to be included in
41 * a subsequent release, you agree by submitting the changes that
42 * those changes may be distributed with this exception intact.
43 *
44 * If you write modifications of your own for SANE, it is your choice
45 * whether to permit this exception to apply to your modifications.
46 * If you do not wish that, delete this exception notice.
47 * <hr>
48 */
49
50 /*************************** some definitions *********************************/
51
52 #define _BACKSTEPS 120
53 #define _FORWARDSTEPS 120
54
55 /**************************** local vars *************************************/
56
57 static TimerDef u12motor_Timer;
58
59
60 /*************************** local functions *********************************/
61
62 /**
63 */
u12motor_DownloadNullScanStates(U12_Device * dev)64 static void u12motor_DownloadNullScanStates( U12_Device *dev )
65 {
66 memset( dev->scanStates, 0, _SCANSTATE_BYTES );
67 u12io_DownloadScanStates( dev );
68 }
69
70 /**
71 */
u12motor_Force16Steps(U12_Device * dev,int dir)72 static void u12motor_Force16Steps( U12_Device *dev, int dir )
73 {
74 u_long dw;
75
76 if( dir == _DIR_FW )
77 u12io_DataToRegister( dev, REG_MOTOR0CONTROL, _FORWARD_MOTOR );
78 else if( dir == _DIR_BW )
79 u12io_DataToRegister( dev, REG_MOTOR0CONTROL, _BACKWARD_MOTOR );
80
81 for( dw = 16; dw; dw-- ) {
82 u12io_RegisterToScanner( dev, REG_FORCESTEP );
83 _DODELAY( 10 );
84 }
85 }
86
87 /**
88 */
u12motor_ModuleFreeRun(U12_Device * dev,u_long steps)89 static void u12motor_ModuleFreeRun( U12_Device *dev, u_long steps )
90 {
91 SANE_Byte rb[6];
92
93 rb[0] = REG_MOTORFREERUNCOUNT1; rb[1] = _HIBYTE(steps);
94 rb[2] = REG_MOTORFREERUNCOUNT0; rb[3] = _LOBYTE(steps);
95 rb[4] = REG_MOTORFREERUNTRIGGER; rb[5] = 0;
96
97 u12io_DataToRegs( dev, rb, 3 );
98 }
99
100 /**
101 */
u12motor_PositionYProc(U12_Device * dev,u_long steps)102 static SANE_Status u12motor_PositionYProc( U12_Device *dev, u_long steps )
103 {
104 TimerDef timer;
105
106 DBG( _DBG_INFO, "u12motor_PositionYProc()\n" );
107 u12io_StartTimer( &timer, _SECOND * 5 );
108
109 u12io_ResetFifoLen();
110 while(!(u12io_GetScanState( dev ) & _SCANSTATE_STOP) &&
111 (!u12io_CheckTimer( &timer )));
112 _DODELAY( 12 );
113 u12motor_ModuleFreeRun( dev, steps );
114 _DODELAY( 15 );
115
116 u12io_StartTimer( &timer, _SECOND * 30 );
117 do {
118 if( !(u12io_GetExtendedStatus( dev ) & _STILL_FREE_RUNNING)) {
119 break;
120 }
121
122 if( u12io_IsEscPressed()) {
123 DBG( _DBG_INFO, "* CANCEL detected!\n" );
124 return SANE_STATUS_CANCELLED;
125 }
126
127 } while( !u12io_CheckTimer( &timer ));
128 DBG( _DBG_INFO, "u12motor_PositionYProc() - done\n" );
129 return SANE_STATUS_GOOD;
130 }
131
132 /** initialize this module and setup the correct function pointer according
133 * to the ASIC
134 */
u12motor_PositionModuleToHome(U12_Device * dev)135 static void u12motor_PositionModuleToHome( U12_Device *dev )
136 {
137 SANE_Byte rb[50];
138 SANE_Byte save, saveModel;
139 int c = 0;
140
141 DBG( _DBG_INFO, "u12motor_PositionModuleToHome()\n" );
142 saveModel = dev->regs.RD_ModelControl;
143
144 dev->scan.refreshState = SANE_FALSE;
145 u12motor_DownloadNullScanStates( dev );
146
147 _DODELAY( 125 );
148 save = dev->shade.intermediate;
149
150 dev->shade.intermediate = _ScanMode_AverageOut;
151 u12hw_InitAsic( dev, SANE_FALSE );
152 dev->shade.intermediate = save;
153
154 _SET_REG( rb, c, REG_MODECONTROL, _ModeScan );
155 _SET_REG( rb, c, REG_RESETMTSC, 0 );
156 _SET_REG( rb, c, REG_SCANCONTROL1, 0 );
157 _SET_REG( rb, c, REG_MODELCONTROL, (dev->ModelCtrl | _MODEL_DPI300));
158 _SET_REG( rb, c, REG_LINECONTROL, 80 );
159 _SET_REG( rb, c, REG_XSTEPTIME, dev->XStepBack );
160 _SET_REG( rb, c, REG_MOTORDRVTYPE, dev->MotorPower );
161 _SET_REG( rb, c, REG_MOTOR0CONTROL, (_MotorHHomeStop | _MotorOn |
162 _MotorHQuarterStep | _MotorPowerEnable));
163 _SET_REG( rb, c, REG_STEPCONTROL, (_MOTOR0_SCANSTATE | _MOTOR_FREERUN));
164 u12io_DataToRegs( dev, rb, c );
165
166 memset( dev->scanStates, 0x88, _SCANSTATE_BYTES );
167 u12io_DownloadScanStates( dev );
168
169 u12io_RegisterToScanner( dev, REG_REFRESHSCANSTATE );
170 dev->regs.RD_ModelControl = saveModel;
171 }
172
173 /** function to bring the sensor back home
174 */
u12motor_ToHomePosition(U12_Device * dev,SANE_Bool wait)175 static void u12motor_ToHomePosition( U12_Device *dev, SANE_Bool wait )
176 {
177 TimerDef timer;
178
179 DBG( _DBG_INFO, "Waiting for Sensor to be back in position\n" );
180 if( !(u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER)) {
181
182 u12motor_PositionModuleToHome( dev );
183
184 if( wait ) {
185 u12io_StartTimer( &timer, _SECOND * 20);
186 do {
187 if( u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER)
188 break;
189 } while( !u12io_CheckTimer( &timer ));
190 }
191 }
192 DBG( _DBG_INFO, "- done !\n" );
193 }
194
195 /**
196 */
u12motor_BackToHomeSensor(U12_Device * dev)197 static SANE_Status u12motor_BackToHomeSensor( U12_Device *dev )
198 {
199 SANE_Byte rb[20];
200 int c;
201 TimerDef timer;
202
203 DBG( _DBG_INFO, "u12Motor_BackToHomeSensor()\n" );
204
205 c = 0;
206 _SET_REG( rb, c, REG_STEPCONTROL, _MOTOR0_SCANSTATE );
207 _SET_REG( rb, c, REG_MODECONTROL, _ModeScan );
208
209 u12io_DataToRegs( dev, rb, c );
210
211 u12motor_Force16Steps( dev, _DIR_NONE );
212
213 /* stepping every state */
214 memset( dev->scanStates, 0x88, _SCANSTATE_BYTES );
215 u12io_DownloadScanStates( dev );
216 _DODELAY(50);
217
218 u12io_StartTimer( &timer, _SECOND * 2 );
219
220 u12io_ResetFifoLen();
221 while(!(u12io_GetScanState( dev ) & _SCANSTATE_STOP) &&
222 !u12io_CheckTimer( &timer )) {
223 if( u12io_IsEscPressed()) {
224 DBG( _DBG_INFO, "* CANCEL detected!\n" );
225 return SANE_STATUS_CANCELLED;
226 }
227 }
228
229 u12motor_Force16Steps( dev, _DIR_BW );
230 dev->regs.RD_ModeControl = _ModeScan;
231
232 c = 0;
233
234 if(!(dev->DataInf.dwScanFlag & _SCANDEF_TPA)) {
235 _SET_REG( rb, c, REG_LINECONTROL, _LOBYTE(dev->shade.wExposure));
236 _SET_REG( rb, c, REG_XSTEPTIME, _LOBYTE(dev->shade.wXStep));
237 } else {
238 _SET_REG( rb, c, REG_LINECONTROL, _DEFAULT_LINESCANTIME );
239 _SET_REG( rb, c, REG_XSTEPTIME, 6 );
240 }
241
242 _SET_REG( rb, c, REG_STEPCONTROL, (_MOTOR_FREERUN | _MOTOR0_SCANSTATE));
243 _SET_REG( rb, c, REG_MOTOR0CONTROL,
244 (_MotorHQuarterStep | _MotorOn | _MotorDirBackward |
245 _MotorPowerEnable | _MotorHHomeStop));
246 _SET_REG( rb, c, REG_REFRESHSCANSTATE, 0);
247 u12io_DataToRegs( dev, rb, c );
248
249 u12io_StartTimer( &timer, _SECOND * 5 );
250 do {
251 if( u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER )
252 break;
253
254 if( u12io_IsEscPressed()) {
255 DBG( _DBG_INFO, "* CANCEL detected!\n" );
256 return SANE_STATUS_CANCELLED;
257 }
258
259 _DODELAY( 55 );
260
261 } while( !u12io_CheckTimer( &timer ));
262
263 c = 0;
264 _SET_REG( rb, c, REG_LINECONTROL, dev->regs.RD_LineControl);
265 _SET_REG( rb, c, REG_XSTEPTIME, dev->regs.RD_XStepTime);
266 u12io_DataToRegs( dev, rb, c );
267
268 DBG( _DBG_INFO, "* LineCtrl=0x%02x, XStepTime=0x%02x\n",
269 dev->regs.RD_LineControl, dev->regs.RD_XStepTime );
270
271 u12motor_DownloadNullScanStates( dev );
272 return SANE_STATUS_GOOD;
273 }
274
275 /**
276 */
u12motor_ModuleToHome(U12_Device * dev)277 static SANE_Status u12motor_ModuleToHome( U12_Device *dev )
278 {
279 SANE_Status res;
280
281 DBG( _DBG_INFO, "u12motor_ModuleToHome()\n" );
282 if(!(u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER)) {
283
284 u12io_DataToRegister( dev, REG_MOTOR0CONTROL,
285 (SANE_Byte)(dev->regs.RD_Motor0Control|_MotorDirForward));
286
287 res = u12motor_PositionYProc( dev, 40 );
288 if( SANE_STATUS_GOOD != res )
289 return res;
290
291 res = u12motor_BackToHomeSensor( dev );
292 if( SANE_STATUS_GOOD != res )
293 return res;
294
295 _DODELAY( 250 );
296 }
297 DBG( _DBG_INFO, "* done.\n" );
298 return SANE_STATUS_GOOD;
299 }
300
301 /**
302 */
u12motor_WaitForPositionY(U12_Device * dev)303 static SANE_Status u12motor_WaitForPositionY( U12_Device *dev )
304 {
305 SANE_Byte rb[20];
306 SANE_Status res;
307 SANE_Byte bXStep;
308 int c;
309 u_long dwBeginY;
310
311 c = 0;
312 dwBeginY = (u_long)dev->DataInf.crImage.y * 4 + dev->scan.dwScanOrigin;
313
314 if( dev->DataInf.wPhyDataType <= COLOR_256GRAY ) {
315 if( dev->f0_8_16 )
316 dwBeginY += 16;
317 else
318 dwBeginY += 8;
319 }
320
321 bXStep = (SANE_Byte)((dev->DataInf.wPhyDataType <= COLOR_256GRAY) ?
322 dev->XStepMono : dev->XStepColor);
323
324 if( dev->shade.intermediate & _ScanMode_AverageOut )
325 bXStep = 8;
326
327 u12motor_Force16Steps( dev, _DIR_NONE );
328 dwBeginY -= 16;
329
330 if( dwBeginY > (_RFT_SCANNING_ORG + _YOFFSET) &&
331 bXStep < dev->regs.RD_XStepTime ) {
332
333 u12io_DataToRegister( dev, REG_MOTORDRVTYPE, dev->MotorPower );
334 _DODELAY( 12 );
335 u12io_DataToRegister( dev, REG_XSTEPTIME, bXStep);
336 u12io_DataToRegister( dev, REG_EXTENDEDXSTEP, 0 );
337 u12io_DataToRegister( dev, REG_SCANCONTROL1,
338 (SANE_Byte)(dev->regs.RD_ScanControl1 & ~_MFRC_RUNSCANSTATE));
339 res = u12motor_PositionYProc( dev, dwBeginY - 64 );
340 if( SANE_STATUS_GOOD != res )
341 return res;
342 dwBeginY = 64;
343 } else {
344 _SET_REG(rb, c, REG_SCANCONTROL1, dev->regs.RD_ScanControl1 );
345 }
346
347 _SET_REG( rb, c, REG_FIFOFULLEN0, _LOBYTE(dev->regs.RD_BufFullSize));
348 _SET_REG( rb, c, REG_FIFOFULLEN1, _HIBYTE(dev->regs.RD_BufFullSize));
349 _SET_REG( rb, c, REG_FIFOFULLEN2, _LOBYTE(_HIWORD(dev->regs.RD_BufFullSize)));
350 u12io_DataToRegs( dev, rb, c );
351
352 u12io_DataToRegister( dev, REG_MOTORDRVTYPE, dev->regs.RD_MotorDriverType);
353 _DODELAY( 12 );
354
355 if(!dev->f2003 || (dev->shade.intermediate & _ScanMode_AverageOut) ||
356 ( dev->DataInf.xyAppDpi.y <= 75 &&
357 dev->DataInf.wPhyDataType <= COLOR_256GRAY)) {
358 u12io_DataToRegister( dev, REG_MOTORDRVTYPE,
359 (SANE_Byte)(dev->MotorPower & (_MOTORR_MASK | _MOTORR_STRONG)));
360 } else {
361 u12io_DataToRegister( dev, REG_MOTORDRVTYPE,
362 dev->regs.RD_MotorDriverType );
363 }
364
365 c = 0;
366 _SET_REG( rb, c, REG_XSTEPTIME, dev->regs.RD_XStepTime );
367 _SET_REG( rb, c, REG_EXTENDEDXSTEP, dev->regs.RD_ExtXStepTime );
368 _SET_REG( rb, c, REG_SCANCONTROL1,
369 (SANE_Byte)(dev->regs.RD_ScanControl1 & ~_MFRC_RUNSCANSTATE));
370 u12io_DataToRegs( dev, rb, c );
371
372 if( dev->DataInf.dwScanFlag & _SCANDEF_PREVIEW ) {
373
374 TimerDef timer;
375
376 u12motor_ModuleFreeRun( dev, dwBeginY );
377 _DODELAY( 15 );
378
379 u12io_StartTimer( &timer, (_SECOND * 20));
380
381 while(( u12io_GetExtendedStatus( dev ) & _STILL_FREE_RUNNING) &&
382 !u12io_CheckTimer(&timer));
383 u12io_DataToRegister( dev, REG_MODECONTROL, _ModeScan );
384 } else {
385 u12motor_PositionYProc( dev, dwBeginY );
386 u12io_RegisterToScanner( dev, REG_REFRESHSCANSTATE );
387 }
388 return SANE_STATUS_GOOD;
389 }
390
391 /**
392 */
u12motor_ForceToLeaveHomePos(U12_Device * dev)393 static void u12motor_ForceToLeaveHomePos( U12_Device *dev )
394 {
395 SANE_Byte rb[4];
396 TimerDef timer;
397
398 DBG( _DBG_INFO, "u12motor_ForceToLeaveHomePos()\n" );
399 rb[0] = REG_STEPCONTROL;
400 rb[1] = _MOTOR0_ONESTEP;
401 rb[2] = REG_MOTOR0CONTROL;
402 rb[3] = _FORWARD_MOTOR;
403 u12io_DataToRegs( dev, rb, 2 );
404
405 u12io_StartTimer( &timer, _SECOND );
406
407 do {
408 if( !(u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER))
409 break;
410
411 u12io_RegisterToScanner( dev, REG_FORCESTEP );
412 _DODELAY( 10 );
413
414 } while( !u12io_CheckTimer( &timer ));
415
416 u12io_DataToRegister( dev, REG_STEPCONTROL, _MOTOR0_SCANSTATE );
417 }
418
419 /** move the sensor to the appropriate shading position
420 */
u12motor_GotoShadingPosition(U12_Device * dev)421 static SANE_Status u12motor_GotoShadingPosition( U12_Device *dev )
422 {
423 SANE_Byte rb[20];
424 SANE_Status res;
425 int c;
426
427 DBG( _DBG_INFO, "u12motor_GotoShadingPosition()\n" );
428 res = u12motor_ModuleToHome( dev );
429 if( SANE_STATUS_GOOD == res )
430 return res;
431
432 /* position to somewhere under the transparency adapter */
433 if( dev->DataInf.dwScanFlag & _SCANDEF_TPA ) {
434
435 u12motor_ForceToLeaveHomePos( dev );
436 u12motor_DownloadNullScanStates( dev );
437
438 c = 0;
439 _SET_REG( rb, c, REG_STEPCONTROL, _MOTOR0_SCANSTATE );
440 _SET_REG( rb, c, REG_MODECONTROL, _ModeScan);
441 _SET_REG( rb, c, REG_MOTOR0CONTROL, _FORWARD_MOTOR );
442 _SET_REG( rb, c, REG_XSTEPTIME, 6);
443 _SET_REG( rb, c, REG_EXTENDEDXSTEP, 0);
444 _SET_REG( rb, c, REG_SCANCONTROL1, _MFRC_BY_XSTEP);
445 u12io_DataToRegs( dev, rb, c );
446
447 res = u12motor_PositionYProc( dev, _TPA_SHADINGORG );
448 if( SANE_STATUS_GOOD != res )
449 return res;
450 }
451 DBG( _DBG_INFO, "* Position reached\n" );
452 return SANE_STATUS_GOOD;
453 }
454
455 /**
456 */
u12motor_ModuleForwardBackward(U12_Device * dev)457 static void u12motor_ModuleForwardBackward( U12_Device *dev )
458 {
459 DBG( _DBG_INFO, "u12motor_ModuleForwardBackward()\n" );
460
461 switch( dev->scan.bModuleState ) {
462
463 case _MotorInNormalState:
464 DBG( _DBG_INFO, "* _MotorInNormalState\n" );
465 dev->scan.bModuleState = _MotorGoBackward;
466 u12io_DataToRegister( dev, REG_SCANCONTROL1,
467 (SANE_Byte)(dev->regs.RD_ScanControl1 & ~_MFRC_RUNSCANSTATE));
468 u12io_DataToRegister( dev, REG_MOTOR0CONTROL,
469 (SANE_Byte)(dev->regs.RD_Motor0Control & ~_MotorDirForward));
470
471 u12motor_ModuleFreeRun( dev, _BACKSTEPS );
472 u12io_StartTimer( &u12motor_Timer, (15 * _MSECOND));
473 break;
474
475 case _MotorGoBackward:
476 DBG( _DBG_INFO, "* _MotorGoBackward\n" );
477 if( u12io_CheckTimer( &u12motor_Timer)) {
478 if(!(u12io_GetExtendedStatus( dev ) & _STILL_FREE_RUNNING )) {
479 dev->scan.bModuleState = _MotorInStopState;
480 u12io_StartTimer( &u12motor_Timer, (50 *_MSECOND));
481 }
482 }
483 break;
484
485 case _MotorInStopState:
486 DBG( _DBG_INFO, "* _MotorInStopState\n" );
487 if( u12io_CheckTimer( &u12motor_Timer )) {
488
489 if( u12io_GetFifoLength( dev ) < dev->scan.dwMaxReadFifo ) {
490 dev->scan.bModuleState = _MotorAdvancing;
491 u12io_DataToRegister( dev, REG_SCANCONTROL1,
492 dev->regs.RD_ScanControl1);
493 u12io_DataToRegister( dev, REG_MOTOR0CONTROL,
494 dev->regs.RD_Motor0Control);
495 u12motor_ModuleFreeRun( dev, _FORWARDSTEPS );
496 u12io_StartTimer( &u12motor_Timer, (15 * _MSECOND));
497 }
498 }
499 break;
500
501 case _MotorAdvancing:
502 DBG( _DBG_INFO, "* _MotorAdvancing\n" );
503 if( u12io_CheckTimer( &u12motor_Timer)) {
504 if( !(u12io_GetScanState( dev ) & _SCANSTATE_STOP))
505 dev->scan.bModuleState = _MotorInNormalState;
506 else {
507 if (!(u12io_GetExtendedStatus( dev ) & _STILL_FREE_RUNNING )) {
508 u12io_RegisterToScanner( dev, REG_REFRESHSCANSTATE );
509 dev->scan.bModuleState = _MotorInNormalState;
510 }
511 }
512 }
513 break;
514 }
515 }
516
517 /* END U12-MOTOR.C ..........................................................*/
518