1 /* sane - Scanner Access Now Easy.
2
3 pieusb_scancmd.c
4
5 Copyright (C) 2012-2015 Jan Vleeshouwers, Michael Rickmann, Klaus Kaempf
6
7 This file is part of the SANE package.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22 As a special exception, the authors of SANE give permission for
23 additional uses of the libraries contained in this release of SANE.
24
25 The exception is that, if you link a SANE library with other files
26 to produce an executable, this does not by itself cause the
27 resulting executable to be covered by the GNU General Public
28 License. Your use of that executable is in no way restricted on
29 account of linking the SANE library code into it.
30
31 This exception does not, however, invalidate any other reasons why
32 the executable file might be covered by the GNU General Public
33 License.
34
35 If you submit changes to SANE to the maintainers to be included in
36 a subsequent release, you agree by submitting the changes that
37 those changes may be distributed with this exception intact.
38
39 If you write modifications of your own for SANE, it is your choice
40 whether to permit this exception to apply to your modifications.
41 If you do not wish that, delete this exception notice. */
42
43 /* =========================================================================
44 *
45 * Pieusb scanner commands
46 *
47 * Each scanner command has its own function.
48 * See the sort description preceding each function.
49 *
50 * ========================================================================= */
51
52 #define DEBUG_DECLARE_ONLY
53
54 #include "pieusb.h"
55 #include "pieusb_scancmd.h"
56 #include "pieusb_usb.h"
57
58 #ifdef HAVE_ALLOCA_H
59 #include <alloca.h>
60 #endif
61
62 #include <time.h> /* for time() */
63
64 static void _prep_scsi_cmd(SANE_Byte* command_bytes, SANE_Byte command, SANE_Word size);
65
66 /* =========================================================================
67 *
68 * Pieusb utility functions
69 *
70 * ========================================================================= */
71
72 /*
73 * Get the unsigned char value in the array at given offset
74 */
75 static SANE_Byte
_get_byte(SANE_Byte* array, SANE_Byte offset)76 _get_byte(SANE_Byte* array, SANE_Byte offset) {
77 return *(array+offset);
78 }
79
80 /*
81 * Set the array at given offset to the given unsigned char value
82 */
83 static void
_set_byte(SANE_Byte val, SANE_Byte* array, SANE_Byte offset)84 _set_byte(SANE_Byte val, SANE_Byte* array, SANE_Byte offset) {
85 *(array+offset) = val;
86 }
87
88
89 /*
90 * Get the unsigned short value in the array at given offset.
91 * All data in structures is little-endian, so the LSB comes first
92 * SANE_Int is 4 bytes, but that is not a problem.
93 */
94 static SANE_Int
_get_short(SANE_Byte* array, SANE_Byte offset)95 _get_short(SANE_Byte* array, SANE_Byte offset) {
96 SANE_Int i = *(array+offset+1);
97 i <<= 8;
98 i += *(array+offset);
99 return i;
100 }
101
102
103 /*
104 * Put the bytes of a short int value into an unsigned char array
105 * All data in structures is little-endian, so start with LSB
106 */
107 static void
_set_short(SANE_Word val, SANE_Byte* array, SANE_Byte offset)108 _set_short(SANE_Word val, SANE_Byte* array, SANE_Byte offset) {
109 *(array+offset) = val & 0xFF;
110 *(array+offset+1) = (val>>8) & 0xFF;
111 }
112
113
114 /*
115 * Get the signed int value in the array at given offset.
116 * All data in structures is little-endian, so the LSB comes first
117 */
118 static SANE_Int
_get_int(SANE_Byte* array, SANE_Byte offset)119 _get_int(SANE_Byte* array, SANE_Byte offset) {
120 SANE_Int i = *(array+offset+3);
121 i <<= 8;
122 i += *(array+offset+2);
123 i <<= 8;
124 i += *(array+offset+1);
125 i <<= 8;
126 i += *(array+offset);
127 return i;
128 }
129
130 #if 0 /* unused */
131 /*
132 * Put the bytes of a signed int value into an unsigned char array
133 * All data in structures is little-endian, so start with LSB
134 */
135 static void
136 _set_int(SANE_Word val, SANE_Byte* array, SANE_Byte offset) {
137 *(array+offset) = val & 0xFF;
138 *(array+offset+1) = (val>>8) & 0xFF;
139 *(array+offset+2) = (val>>16) & 0xFF;
140 *(array+offset+3) = (val>>24) & 0xFF;
141 }
142 #endif
143
144 /*
145 * Copy count unsigned char values from src to dst
146 */
147 static void
_copy_bytes(SANE_Byte* dst, SANE_Byte* src, SANE_Byte count)148 _copy_bytes(SANE_Byte* dst, SANE_Byte* src, SANE_Byte count) {
149 SANE_Byte k;
150 for (k=0; k<count; k++) {
151 *dst++ = *src++;
152 }
153 }
154
155
156 /*
157 * Get count unsigned short values in the array at given offset.
158 * All data in structures is little-endian, so the MSB comes first.
159 * SANE_Word is 4 bytes, but that is not a problem.
160 */
161 static void
_get_shorts(SANE_Word* dst, SANE_Byte* src, SANE_Byte count)162 _get_shorts(SANE_Word* dst, SANE_Byte* src, SANE_Byte count) {
163 SANE_Byte k;
164 for (k=0; k<count; k++) {
165 *dst = *(src+2*k+1);
166 *dst <<= 8;
167 *dst++ += *(src+2*k);
168 }
169 }
170
171 /*
172 * Copy an unsigned short array of given size
173 * All data in structures is little-endian, so start with MSB of each short.
174 * SANE_Word is 4 bytes, but that is not a problem. All MSB 2 bytes are ignored.
175 */
176 static void
_set_shorts(SANE_Word* src, SANE_Byte* dst, SANE_Byte count)177 _set_shorts(SANE_Word* src, SANE_Byte* dst, SANE_Byte count) {
178 SANE_Byte k;
179 for (k=0; k<count; k++) {
180 *(dst+2*k) = *src & 0xFF;
181 *(dst+2*k+1) = ((*src++)>>8) & 0xFF;
182 }
183 }
184
185
186 /**
187 * Perform a TEST UNIT READY (SCSI command code 0x00)
188 * Returns status->pieusb_status:
189 * - PIEUSB_STATUS_GOOD if device is ready
190 * - PIEUSB_STATUS_DEVICE_BUSY if device is still busy after timeout
191 * - other SANE status code if TEST UNIT READY failed or if it returned
192 * CHECK CONDITION and REQUEST SENSE failed
193 *
194 * @param device_number Device number
195 * @return Pieusb_Command_Status SANE_STATUS_GOOD if ready, SANE_STATUS_DEVICE_BUSY if not
196 */
197 void
sanei_pieusb_cmd_test_unit_ready(SANE_Int device_number, struct Pieusb_Command_Status *status)198 sanei_pieusb_cmd_test_unit_ready(SANE_Int device_number, struct Pieusb_Command_Status *status)
199 {
200 SANE_Byte command[SCSI_COMMAND_LEN];
201
202 DBG (DBG_info_scan, "sanei_pieusb_cmd_test_unit_ready()\n");
203
204 _prep_scsi_cmd (command, SCSI_TEST_UNIT_READY, 0);
205
206 status->pieusb_status = sanei_pieusb_command (device_number, command, NULL, 0);
207
208 DBG (DBG_info_scan, "sanei_pieusb_cmd_test_unit_ready() return status = %s\n",
209 sane_strstatus (sanei_pieusb_convert_status (status->pieusb_status)));
210 }
211
212 /**
213 * slide action
214 * @param action SLIDE_NEXT, SLIDE_PREV, SLIDE_INIT, SLIDE_RELOAD
215 * @return Pieusb_Command_Status
216 */
217
218 void
sanei_pieusb_cmd_slide(SANE_Int device_number, slide_action action, struct Pieusb_Command_Status *status)219 sanei_pieusb_cmd_slide(SANE_Int device_number, slide_action action, struct Pieusb_Command_Status *status)
220 {
221 SANE_Byte command[SCSI_COMMAND_LEN];
222 #define SLIDE_DATA_SIZE 4
223 SANE_Byte data[SLIDE_DATA_SIZE];
224
225 DBG (DBG_info_scan, "sanei_pieusb_cmd_slide(0x%02x)\n", action);
226
227 _prep_scsi_cmd(command, SCSI_SLIDE, SLIDE_DATA_SIZE);
228 memset(data, '\0', SLIDE_DATA_SIZE);
229 data[0] = action;
230 data[1] = 0x01;
231
232 status->pieusb_status = sanei_pieusb_command(device_number, command, data, SLIDE_DATA_SIZE);
233 #undef SLIDE_DATA_SIZE
234 }
235
236 /**
237 * Perform a REQUEST SENSE (SCSI command code 0x03)
238 * Returns status->pieusb_status:
239 * - PIEUSB_STATUS_GOOD is the command executes OK
240 * - other SANE status code if REQUEST SENSE fails
241 * The sense fields in status are always 0. A REQUEST SENSE is not repeated if
242 * the device returns PIEUSB_STATUS_DEVICE_BUSY.
243 *
244 * @param device_number Device number
245 * @param sense Sense data
246 * @param status Command result status
247 * @see struct Pieusb_Sense
248 */
249 void
sanei_pieusb_cmd_get_sense(SANE_Int device_number, struct Pieusb_Sense* sense, struct Pieusb_Command_Status *status, PIEUSB_Status *ret)250 sanei_pieusb_cmd_get_sense(SANE_Int device_number, struct Pieusb_Sense* sense, struct Pieusb_Command_Status *status, PIEUSB_Status *ret)
251 {
252 SANE_Byte command[SCSI_COMMAND_LEN];
253 #define DATA_SIZE 14
254 SANE_Int size = DATA_SIZE;
255 SANE_Byte data[DATA_SIZE];
256 PIEUSB_Status st;
257 SANE_Char* sd;
258
259 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_sense()\n");
260
261 _prep_scsi_cmd(command, SCSI_REQUEST_SENSE, size);
262
263 memset(data, '\0', size);
264 st = sanei_pieusb_command(device_number, command, data, size);
265 if (st != PIEUSB_STATUS_GOOD) {
266 status->pieusb_status = st;
267 /*FIXME*/
268 return;
269 }
270
271 /* Decode data received */
272 sense->errorCode = _get_byte (data, 0);
273 sense->segment = _get_byte (data, 1);
274 sense->senseKey = _get_byte (data, 2);
275 _copy_bytes (sense->info, data+3, 4);
276 sense->addLength = _get_byte (data, 7);
277 _copy_bytes (sense->cmdInfo, data+8, 4);
278 sense->senseCode = _get_byte (data, 12);
279 sense->senseQualifier = _get_byte (data, 13);
280 status->pieusb_status = PIEUSB_STATUS_GOOD;
281 #undef DATA_SIZE
282 DBG (DBG_info_scan, "\tsense details:\n");
283 DBG (DBG_info_scan, "\t\terror......... : 0x%02x\n", sense->errorCode);
284 DBG (DBG_info_scan, "\t\tsegment....... : %d\n", sense->segment);
285 DBG (DBG_info_scan, "\t\tsenseKey...... : 0x%02x\n", sense->senseKey);
286 DBG (DBG_info_scan, "\t\tinfo.......... : %02x %02x %02x %02x\n", sense->info[0], sense->info[1], sense->info[2], sense->info[3]);
287 DBG (DBG_info_scan, "\t\taddLength..... : %d\n", sense->addLength);
288 DBG (DBG_info_scan, "\t\tcmdInfo....... : %02x %02x %02x %02x\n", sense->cmdInfo[0], sense->cmdInfo[1], sense->cmdInfo[2], sense->cmdInfo[3]);
289 DBG (DBG_info_scan, "\t\tsenseCode..... : 0x%02x\n", sense->senseCode);
290 DBG (DBG_info_scan, "\t\tsenseQualifier : 0x%02x\n", sense->senseQualifier);
291 sd = sanei_pieusb_decode_sense (sense, ret?ret:&st);
292 DBG (DBG_info_scan, "\tsense: %s\n", sd);
293 free(sd);
294 }
295
296 /**
297 * Read the scan frame with the specified index. This requires two
298 * commands, one to ask the device to prepare the pattern, and one to read it.
299 *
300 * @param device_number Device number
301 * @param frame Scan frame
302 * @return Pieusb_Command_Status
303 * @see Pieusb_Scan_Frame
304 */
305 void
sanei_pieusb_cmd_get_scan_frame(SANE_Int device_number, SANE_Int index, struct Pieusb_Scan_Frame* frame, struct Pieusb_Command_Status *status)306 sanei_pieusb_cmd_get_scan_frame(SANE_Int device_number, SANE_Int index, struct Pieusb_Scan_Frame* frame, struct Pieusb_Command_Status *status)
307 {
308 SANE_Byte command[SCSI_COMMAND_LEN];
309 #define FRAME_SIZE 256 /* Assumed maximum frame size */
310 SANE_Int size = FRAME_SIZE;
311 SANE_Byte data[FRAME_SIZE];
312 PIEUSB_Status st;
313
314 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_scan_frame()\n");
315
316 /* Ask scanner to prepare the scan frame with the given index. Only SCSI_COMMAND_LEN bytes of data. */
317 _prep_scsi_cmd (command, SCSI_WRITE, SCSI_COMMAND_LEN);
318 memset (data, '\0', SCSI_COMMAND_LEN);
319 data[0] = SCSI_SCAN_FRAME | 0x80; /* set bit 7 means prepare read */
320 data[4] = index;
321
322 st = sanei_pieusb_command (device_number, command, data, SCSI_COMMAND_LEN);
323 if (st != PIEUSB_STATUS_GOOD) {
324 status->pieusb_status = st;
325 /* FIXME */
326 return;
327 }
328
329 /* Read scan frame */
330 _prep_scsi_cmd (command, SCSI_READ, size);
331
332 memset(data, '\0', size);
333 status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
334
335 /* Decode data */
336 frame->index = _get_byte (data, 4);
337 frame->x0 = _get_short (data, 6);
338 frame->y0 = _get_short (data, 8);
339 frame->x1 = _get_short (data, 10);
340 frame->y1 = _get_short (data, 12);
341
342 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_scan_frame() set:\n");
343 DBG (DBG_info_scan, " x0,y0 = %d,%d\n", frame->x0, frame->y0);
344 DBG (DBG_info_scan, " x1,y1 = %d,%d\n", frame->x1, frame->y1);
345 DBG (DBG_info_scan, " index = %d\n", frame->index);
346 #undef FRAME_SIZE
347 }
348
349 /**
350 * command 17 - unknown
351 */
352
353 void
sanei_pieusb_cmd_17(SANE_Int device_number, SANE_Int value, struct Pieusb_Command_Status *status)354 sanei_pieusb_cmd_17(SANE_Int device_number, SANE_Int value, struct Pieusb_Command_Status *status)
355 {
356 SANE_Byte command[SCSI_COMMAND_LEN];
357 #define CMD_17_SIZE 6
358 SANE_Byte data[CMD_17_SIZE];
359
360 DBG (DBG_info_scan, "sanei_pieusb_cmd_17(%d)\n", value);
361
362 _prep_scsi_cmd (command, SCSI_WRITE, CMD_17_SIZE);
363 memset (data, '\0', CMD_17_SIZE);
364 _set_short (SCSI_CMD_17, data, 0);
365 _set_short (2, data, 2);
366 _set_short (value, data, 4);
367
368 status->pieusb_status = sanei_pieusb_command (device_number, command, data, CMD_17_SIZE);
369 #undef CMD_17_SIZE
370 if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
371 DBG (DBG_info_scan, "sanei_pieusb_cmd_17 failed: 0x%02x\n", status->pieusb_status);
372 return;
373 }
374 }
375
376 /**
377 * Read the shading data parameters. This requires two
378 * commands, one to ask the device to prepare the value, and one to read it.
379 *
380 * @param device_number Device number
381 * @param shading Shading data parameters
382 * @return Pieusb_Command_Status
383 * @see Pieusb_Shading_Parameters
384 */
385 void
sanei_pieusb_cmd_get_shading_parms(SANE_Int device_number, struct Pieusb_Shading_Parameters_Info* shading, struct Pieusb_Command_Status *status)386 sanei_pieusb_cmd_get_shading_parms(SANE_Int device_number, struct Pieusb_Shading_Parameters_Info* shading, struct Pieusb_Command_Status *status)
387 {
388 SANE_Byte command[SCSI_COMMAND_LEN];
389 #define SHADING_SIZE 32
390 #define PREP_READ_SIZE 6
391 SANE_Int size = SHADING_SIZE;
392 SANE_Byte data[SHADING_SIZE];
393 int k;
394
395 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_shading_parms()\n");
396
397 /* Ask scanner to prepare the scan frame with the given index. Only SCSI_COMMAND_LEN bytes of data. */
398 _prep_scsi_cmd (command, SCSI_WRITE, SCSI_COMMAND_LEN);
399 memset (data, '\0', PREP_READ_SIZE);
400 data[0] = SCSI_CALIBRATION_INFO | 0x80; /* set bit 7 means prepare read */
401
402 status->pieusb_status = sanei_pieusb_command (device_number, command, data, PREP_READ_SIZE);
403 if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
404 return;
405 }
406
407 /* Read shading parameters */
408 _prep_scsi_cmd(command, SCSI_READ, size);
409
410 memset (data, '\0', size);
411 status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
412 if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
413 return;
414 }
415
416 /* Decode data [32 bytes]
417 0: 95 00 type
418 2: 1c 00 payload len
419 4: 04 entries
420 5: 06 entry size
421 6: 04 00 ?
422 8: 00 10 10 14 1a 1d type send recv nlines pixPerLine(2bytes)
423 14: 08 10 10 14 1a 1d
424 20: 10 10 10 14 1a 1d
425 26: 20 10 10 14 1a 1d
426 */
427 for (k = 0; k < data[4]; k++) {
428 shading[k].type = _get_byte (data, 8 + data[5]*k);
429 shading[k].sendBits = _get_byte (data, 9 + data[5]*k);
430 shading[k].recieveBits = _get_byte (data, 10 + data[5]*k);
431 shading[k].nLines = _get_byte (data, 11 + data[5]*k);
432 shading[k].pixelsPerLine = _get_short (data, 12 + data[5]*k);
433 }
434 #undef PREP_READ_SIZE
435 #undef SHADING_SIZE
436 }
437
438 /**
439 * Read scanned data from the scanner memory into a byte array. The lines
440 * argument specifies how many lines will be read, the size argument specifies
441 * the total amount of bytes in these lines. Use sanei_pieusb_cmd_get_parameters() to
442 * determine the current line size and the number of available lines.\n
443 * If there is scanned data available, it should be read. Waiting too long
444 * causes the scan to stop, probably because a buffer is filled to its limits
445 * (if so, it is approximately 2Mb in size). I haven't tried what happens if you
446 * start reading after a stop. Reading to fast causes the scanner to return
447 * a busy status, which is not a problem.
448 * This is a SCSI READ command (code 0x08). It is distinguished from the other
449 * READ commands by the context in which it is issued: see sanei_pieusb_cmd_start_scan().
450 *
451 * @param device_number
452 * @param data
453 * @param lines
454 * @param size
455 * @return Pieusb_Command_Status
456 */
457 void
sanei_pieusb_cmd_get_scanned_lines(SANE_Int device_number, SANE_Byte* data, SANE_Int lines, SANE_Int size, struct Pieusb_Command_Status *status)458 sanei_pieusb_cmd_get_scanned_lines(SANE_Int device_number, SANE_Byte* data, SANE_Int lines, SANE_Int size, struct Pieusb_Command_Status *status)
459 {
460 SANE_Byte command[SCSI_COMMAND_LEN];
461
462 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_scanned_lines(): %d lines (%d bytes)\n", lines, size);
463
464 _prep_scsi_cmd (command, SCSI_READ, lines);
465 memset (data, '\0', size);
466
467 status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
468 }
469
470 /**
471 * Set the scan frame with the given index to the frame. The command is a SCSI
472 * WRITE command (code SCSI_WRITE, write code SCSI_SCAN_FRAME).
473 *
474 * @param device_number Device number
475 * @param index Frame index (0-7)
476 * @param frame Scan frame
477 * @return Pieusb_Command_Status
478 * @see Pieusb_Scan_Frame
479 */
480 void
sanei_pieusb_cmd_set_scan_frame(SANE_Int device_number, SANE_Int index, struct Pieusb_Scan_Frame* frame, struct Pieusb_Command_Status *status)481 sanei_pieusb_cmd_set_scan_frame(SANE_Int device_number, SANE_Int index, struct Pieusb_Scan_Frame* frame, struct Pieusb_Command_Status *status)
482 {
483 SANE_Byte command[SCSI_COMMAND_LEN];
484 #define FRAME_SIZE 14
485 SANE_Int size = FRAME_SIZE;
486 SANE_Byte data[FRAME_SIZE];
487
488 DBG (DBG_info_scan, "sanei_pieusb_cmd_set_scan_frame()\n");
489
490 _prep_scsi_cmd(command, SCSI_WRITE, size);
491
492 DBG (DBG_info_scan, " x0,y0 = %d,%d\n", frame->x0, frame->y0);
493 DBG (DBG_info_scan, " x1,y1 = %d,%d\n", frame->x1, frame->y1);
494 DBG (DBG_info_scan, " index = %d\n", index);
495
496 /* Code data */
497 memset (data, '\0', size);
498 _set_short (SCSI_SCAN_FRAME, data, 0);
499 _set_short (size-4, data, 2); /* size: one frame, 5 shorts */
500 _set_short (index, data, 4);
501 _set_short (frame->x0, data, 6);
502 _set_short (frame->y0, data, 8);
503 _set_short (frame->x1, data, 10);
504 _set_short (frame->y1, data, 12);
505
506 status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
507 #undef FRAME_SIZE
508 }
509
510 /**
511 * Set the relative exposure time to the given values. Only the first
512 * Pieusb_Exposure_Time_Color is used. The command is a SCSI
513 * WRITE command (code SCSI_WRITE, write code SCSI_EXPOSURE).
514 *
515 * @param device_number Device number
516 * @param time Relative exposure time
517 * @return Pieusb_Command_Status
518 * @see Pieusb_Exposure_Time
519 */
520 void
sanei_pieusb_cmd_set_exposure_time(SANE_Int device_number, struct Pieusb_Exposure_Time* time, struct Pieusb_Command_Status *status)521 sanei_pieusb_cmd_set_exposure_time(SANE_Int device_number, struct Pieusb_Exposure_Time* time, struct Pieusb_Command_Status *status)
522 {
523 SANE_Byte command[SCSI_COMMAND_LEN];
524 #define EXPOSURE_DATA_SIZE 8
525 SANE_Byte data[EXPOSURE_DATA_SIZE];
526 struct Pieusb_Exposure_Time_Color *exptime;
527 int i;
528
529 DBG (DBG_info_scan, "sanei_pieusb_cmd_set_exposure_time()\n");
530
531 for (i = 0; i < 3; ++i) { /* R, G, B */
532 _prep_scsi_cmd (command, SCSI_WRITE, EXPOSURE_DATA_SIZE);
533 memset (data, '\0', EXPOSURE_DATA_SIZE);
534 exptime = &(time->color[i]);
535 _set_short (SCSI_EXPOSURE, data, 0);
536 _set_short (EXPOSURE_DATA_SIZE-4, data, 2); /* short: RGB, short: value */
537 _set_short (exptime->filter, data, 4); /* 1: neutral, 2: R, 4: G, 8: B */
538 _set_short (exptime->value, data, 6);
539 status->pieusb_status = sanei_pieusb_command (device_number, command, data, EXPOSURE_DATA_SIZE);
540 if (status->pieusb_status != PIEUSB_STATUS_GOOD)
541 break;
542 }
543
544 #undef EXPOSURE_DATA_SIZE
545 }
546
547 /**
548 * Set the highlight and shadow levels to the given values. Only the first
549 * Pieusb_Highlight_Shadow_Color is used. The command is a SCSI
550 * WRITE command (code SCSI_WRITE, write code SCSI_HIGHLIGHT_SHADOW).
551 *
552 * @param device_number Device number
553 * @param hgltshdw highlight and shadow level
554 * @return Pieusb_Command_Status
555 * @see Pieusb_Highlight_Shadow
556 */
557 void
sanei_pieusb_cmd_set_highlight_shadow(SANE_Int device_number, struct Pieusb_Highlight_Shadow* hgltshdw, struct Pieusb_Command_Status *status)558 sanei_pieusb_cmd_set_highlight_shadow(SANE_Int device_number, struct Pieusb_Highlight_Shadow* hgltshdw, struct Pieusb_Command_Status *status)
559 {
560 SANE_Byte command[SCSI_COMMAND_LEN];
561 #define HIGHLIGHT_SHADOW_SIZE 8
562 SANE_Byte data[HIGHLIGHT_SHADOW_SIZE];
563 struct Pieusb_Highlight_Shadow_Color *color;
564 int i;
565
566 DBG (DBG_info_scan, "sanei_pieusb_cmd_set_highlight_shadow()\n");
567
568 for (i = 0; i < 3; ++i) { /* R, G, B */
569 _prep_scsi_cmd (command, SCSI_WRITE, HIGHLIGHT_SHADOW_SIZE);
570 memset (data, '\0', HIGHLIGHT_SHADOW_SIZE);
571 color = &(hgltshdw->color[i]);
572 _set_short (SCSI_HIGHLIGHT_SHADOW, data, 0);
573 _set_short (HIGHLIGHT_SHADOW_SIZE-4, data, 2); /* short: RGB, short: value */
574 _set_short (color->filter, data, 4); /* 1: neutral, 2: R, 4: G, 8: B */
575 _set_short (color->value, data, 6);
576 status->pieusb_status = sanei_pieusb_command (device_number, command, data, HIGHLIGHT_SHADOW_SIZE);
577 if (status->pieusb_status != PIEUSB_STATUS_GOOD)
578 break;
579 }
580
581 #undef HIGHLIGHT_SHADOW_SIZE
582 }
583
584 /* SCSI PARAM, code 0x0F */
585 /**
586 * Get the parameters of an executed scan, such as width, lines and bytes, which
587 * are needed to calculate the parameters of the READ-commands which read the
588 * actual scan data.
589 *
590 * @param device_number Device number
591 * @param parameters Scan parameters
592 * @return Pieusb_Command_Status
593 * @see Pieusb_Scan_Parameters
594 */
595 void
sanei_pieusb_cmd_get_parameters(SANE_Int device_number, struct Pieusb_Scan_Parameters* parameters, struct Pieusb_Command_Status *status)596 sanei_pieusb_cmd_get_parameters(SANE_Int device_number, struct Pieusb_Scan_Parameters* parameters, struct Pieusb_Command_Status *status)
597 {
598 SANE_Byte command[SCSI_COMMAND_LEN];
599 #define PARAMETER_SIZE 18
600 SANE_Int size = PARAMETER_SIZE;
601 SANE_Byte data[PARAMETER_SIZE];
602
603 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_parameters()\n");
604
605 _prep_scsi_cmd (command, SCSI_PARAM, size);
606 memset (data, '\0', size);
607
608 status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
609 if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
610 return;
611 }
612
613 /* cyberview:
614 * 0: e6 02 width 0x2e6 - 742
615 * 2: e0 02 lines 0x2e0 - 736
616 * 4: e6 02 bytes 0x2e6 - 742
617 * 6: 08 filterOffeset1 8
618 * 7: 08 filterOffset2 8
619 * 8: c9 1c 00 00 period 7369
620 * c: 00 00 scsi transfer rate
621 * e: d7 00 available lines 215
622 * 10:00 00
623 */
624 /* Decode data received */
625 parameters->width = _get_short(data, 0);
626 parameters->lines = _get_short(data, 2);
627 parameters->bytes = _get_short(data, 4);
628 parameters->filterOffset1 = _get_byte(data, 6);
629 parameters->filterOffset2 = _get_byte(data, 7);
630 parameters->period = _get_int(data, 8); /* unused */
631 parameters->scsiTransferRate = _get_short(data, 12); /* unused */
632 parameters->availableLines = _get_short(data, 14);
633
634 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_parameters() read:\n");
635 DBG (DBG_info_scan, " width = %d\n", parameters->width);
636 DBG (DBG_info_scan, " lines = %d\n", parameters->lines);
637 DBG (DBG_info_scan, " bytes = %d\n", parameters->bytes);
638 DBG (DBG_info_scan, " offset1 = %d\n", parameters->filterOffset1);
639 DBG (DBG_info_scan, " offset2 = %d\n", parameters->filterOffset2);
640 DBG (DBG_info_scan, " available lines = %d\n", parameters->availableLines);
641 #undef PARAMETER_SIZE
642 }
643
644 /**
645 * Read INQUIRY block from device (SCSI command code 0x12). This block contains
646 * information about the properties of the scanner.
647 * Returns status->pieusb_status:
648 * - PIEUSB_STATUS_GOOD if the INQUIRY command succeeded
649 * - PIEUSB_STATUS_DEVICE_BUSY if device is busy after repeat retries
650 * - other SANE status code if INQUIRY failed or if it returned CHECK CONDITION
651 * and REQUEST SENSE failed
652 *
653 * @param device_number Device number
654 * @param data Input or output data buffer
655 * @param size Size of the data buffer
656 * @return Pieusb_Command_Status
657 * @see Pieusb_Scanner_Properties
658 */
659 void
sanei_pieusb_cmd_inquiry(SANE_Int device_number, struct Pieusb_Scanner_Properties* inq, SANE_Byte size, struct Pieusb_Command_Status *status)660 sanei_pieusb_cmd_inquiry(SANE_Int device_number, struct Pieusb_Scanner_Properties* inq, SANE_Byte size, struct Pieusb_Command_Status *status)
661 {
662 SANE_Byte command[SCSI_COMMAND_LEN];
663 #define INQUIRY_SIZE 256
664 SANE_Byte data[INQUIRY_SIZE];
665 int k;
666
667 DBG (DBG_info_scan, "sanei_pieusb_cmd_inquiry()\n");
668
669 _prep_scsi_cmd (command, SCSI_INQUIRY, size);
670 memset (data, '\0', INQUIRY_SIZE); /* size may be less than INQUIRY_SIZE, so prevent returning noise */
671
672 status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
673 if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
674 return;
675 }
676
677 /* Decode data received */
678 inq->deviceType = _get_byte(data, 0);
679 inq->additionalLength = _get_byte(data, 4);
680 _copy_bytes((SANE_Byte*)(inq->vendor), data+8, 8); /* Note: not 0-terminated */
681 _copy_bytes((SANE_Byte*)(inq->product), data+16, 16); /* Note: not 0-terminated */
682 _copy_bytes((SANE_Byte*)(inq->productRevision), data+32, 4); /* Note: not 0-terminated */
683 /* 1st Vendor-specific block, 20 bytes, see pie_get_inquiry_values(), partially: */
684 inq->maxResolutionX = _get_short(data, 36);
685 inq->maxResolutionY = _get_short(data, 38);
686 inq->maxScanWidth = _get_short(data, 40);
687 inq->maxScanHeight = _get_short(data, 42);
688 inq->filters = _get_byte(data, 44);
689 inq->colorDepths = _get_byte(data, 45);
690 inq->colorFormat = _get_byte(data, 46);
691 inq->imageFormat = _get_byte(data, 48);
692 inq->scanCapability = _get_byte(data, 49);
693 inq->optionalDevices = _get_byte(data, 50);
694 inq->enhancements = _get_byte(data, 51);
695 inq->gammaBits = _get_byte(data, 52);
696 inq->lastFilter = _get_byte(data, 53);
697 inq->previewScanResolution = _get_short(data, 54);
698 /* 2nd vendor specific block (36 bytes at offset 96) */
699 _copy_bytes((SANE_Byte*)(inq->firmwareVersion), data+96, 4); inq->firmwareVersion[4]=0x00;
700 inq->halftones = _get_byte(data, 100);
701 inq->minumumHighlight = _get_byte(data, 101);
702 inq->maximumShadow = _get_byte(data, 102);
703 inq->calibrationEquation = _get_byte(data, 103);
704 inq->maximumExposure = _get_short(data ,104);
705 inq->minimumExposure = _get_short(data ,106);
706 inq->x0 = _get_short(data, 108);
707 inq->y0 = _get_short(data, 110);
708 inq->x1 = _get_short(data, 112);
709 inq->y1 = _get_short(data, 114);
710 inq->model = _get_short(data, 116);
711 _copy_bytes((SANE_Byte*)(inq->production), data+120, 4);
712 _copy_bytes((SANE_Byte*)(inq->timestamp), data+124, 20);
713 _copy_bytes((SANE_Byte*)(inq->signature), data+144, 40);
714 /* remove newline in signature */
715 for (k=0; k<40; k++) if (inq->signature[k]==0x0a || inq->signature[k]==0x0d) inq->signature[k]=' ';
716 #undef INQUIRY_SIZE
717 }
718
719 /**
720 * Set scan mode parameters, such as resolution, colors to scan, color depth,
721 * color format, and a couple of scan quality settings (sharpen, skip
722 * calibration, fast infrared). It performs the SCSI-command MODE SELECT,
723 * code 0x15.
724 *
725 * @param device_number Device number
726 * @param mode Mode parameters
727 * @return Pieusb_Command_Status
728 * @see Pieusb_Mode
729 */
730 void
sanei_pieusb_cmd_set_mode(SANE_Int device_number, struct Pieusb_Mode* mode, struct Pieusb_Command_Status *status)731 sanei_pieusb_cmd_set_mode(SANE_Int device_number, struct Pieusb_Mode* mode, struct Pieusb_Command_Status *status)
732 {
733 SANE_Byte command[SCSI_COMMAND_LEN];
734 #define MODE_SIZE 16
735 SANE_Int size = MODE_SIZE;
736 SANE_Byte data[MODE_SIZE];
737 SANE_Byte quality;
738
739 DBG (DBG_info_scan, "sanei_pieusb_cmd_set_mode()\n");
740
741 _prep_scsi_cmd(command, SCSI_MODE_SELECT, size);
742
743 DBG (DBG_info_scan, "sanei_pieusb_cmd_set_mode() set:\n");
744 DBG (DBG_info_scan, " resolution = %d\n", mode->resolution);
745 DBG (DBG_info_scan, " passes = %02x\n", mode->passes);
746 DBG (DBG_info_scan, " depth = %02x\n", mode->colorDepth);
747 DBG (DBG_info_scan, " color format = %02x\n", mode->colorFormat);
748 DBG (DBG_info_scan, " sharpen = %d\n", mode->sharpen);
749 DBG (DBG_info_scan, " skip calibration = %d\n", mode->skipShadingAnalysis);
750 DBG (DBG_info_scan, " fast infrared = %d\n", mode->fastInfrared);
751 DBG (DBG_info_scan, " halftone pattern = %d\n", mode->halftonePattern);
752 DBG (DBG_info_scan, " line threshold = %d\n", mode->lineThreshold);
753
754 /* Code data */
755 /* cyberview
756 * 00 0f entries
757 * f4 01 resolution 500
758 * 80 RGB (90: RGBI)
759 * 04 color depth (4: 8 bit, 20: 16 bit)
760 * 04 color format
761 * 00
762 * 01 byte order
763 * 08 quality bitmask: 80=fast infrared, 08=skip shading analysis, 02=sharpen
764 * 00 00
765 * 00 halftone pattern
766 * 80 line threshold
767 * 10 00
768 *
769 * pieusb
770 * 0: 00 0f
771 * 2: e8 03 resolution 1000
772 * 4: 80 passes
773 * 5: 04 color depth
774 * 6: 04 color format
775 * 7: 00
776 * 8: 01 byte order
777 * 9: 02 quality bitmask: sharpen
778 * a: 00 00
779 * c: 00 halftone pattern
780 * d: 7f line threshold
781 * e: 00 00
782 */
783 memset (data, '\0', size);
784 _set_byte (size-1, data, 1);
785 _set_short (mode->resolution, data, 2);
786 _set_byte (mode->passes, data, 4);
787 _set_byte (mode->colorDepth, data, 5);
788 _set_byte (mode->colorFormat, data, 6);
789 _set_byte (mode->byteOrder, data, 8);
790 quality = 0x00;
791 if (mode->sharpen) quality |= 0x02;
792 if (mode->skipShadingAnalysis) quality |= 0x08;
793 if (mode->fastInfrared) quality |= 0x80;
794 _set_byte (quality, data, 9);
795 _set_byte (mode->halftonePattern, data, 12);
796 _set_byte (mode->lineThreshold, data, 13);
797 _set_byte (0x10, data, 14); /* ? */
798
799 status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
800 #undef MODE_SIZE
801 }
802
803 /* SCSI COPY, code 0x18 */
804 /**
805 * Get the currently used CCD-mask, which defines which pixels have been used in
806 * the scan, and which allows to relate scan data to shading data. A mask is a
807 * 5340 byte array which consists only contains the values 0x00 and 0x70. A
808 * value of 0x00 indicates the pixel is used, a value of 0x70 that it is not.\n
809 * The number of 0x00 bytes equals the number of pixels on a line.\n
810 * The mask begins with a number of 0x70 bytes equal to the scan frame x0-value
811 * divided by 2.\n
812 * The SCSI-command COPY (code 0x18) is used for function.
813 *
814 * @param device_number Device number
815 * @param mask
816 * @return Pieusb_Command_Status
817 */
818 void
sanei_pieusb_cmd_get_ccd_mask(SANE_Int device_number, SANE_Byte* mask, SANE_Int mask_size, struct Pieusb_Command_Status *status)819 sanei_pieusb_cmd_get_ccd_mask(SANE_Int device_number, SANE_Byte* mask, SANE_Int mask_size, struct Pieusb_Command_Status *status)
820 {
821 SANE_Byte command[SCSI_COMMAND_LEN];
822
823 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_ccd_mask()\n");
824
825 _prep_scsi_cmd (command, SCSI_COPY, mask_size);
826
827 memset (mask, '\0', mask_size);
828 status->pieusb_status = sanei_pieusb_command (device_number, command, mask, mask_size);
829 }
830
831 /**
832 * Get scan mode parameters, such as resolution, colors to scan, color depth,
833 * color format, and a couple of scan quality settings (sharpen, skip
834 * calibration, fast infrared). It performs the SCSI-command MODE SELECT,
835 * code 0x1A.
836 *
837 * @param device_number Device number
838 * @param mode Mode parameters
839 * @return Pieusb_Command_Status
840 * @see Pieusb_Mode
841 */
842 void
sanei_pieusb_cmd_get_mode(SANE_Int device_number, struct Pieusb_Mode* mode, struct Pieusb_Command_Status *status)843 sanei_pieusb_cmd_get_mode(SANE_Int device_number, struct Pieusb_Mode* mode, struct Pieusb_Command_Status *status)
844 {
845 SANE_Byte command[SCSI_COMMAND_LEN];
846 #define MODE_SIZE 16
847 SANE_Int size = MODE_SIZE;
848 SANE_Byte data[MODE_SIZE];
849 SANE_Byte quality;
850
851 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_mode()\n");
852
853 _prep_scsi_cmd (command, SCSI_MODE_SENSE, size);
854 memset (data, '\0', size);
855
856 status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
857 if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
858 return;
859 }
860
861 /* Decode data received */
862 mode->resolution = _get_short (data, 2);
863 mode->passes = _get_byte (data, 4);
864 mode->colorDepth = _get_byte (data, 5);
865 mode->colorFormat = _get_byte (data, 6);
866 mode->byteOrder = _get_byte (data, 8);
867 quality = _get_byte (data, 9);
868 mode->sharpen = (quality |= 0x02) ? SANE_TRUE : SANE_FALSE;
869 mode->skipShadingAnalysis = (quality |= 0x08) ? SANE_TRUE : SANE_FALSE;
870 mode->fastInfrared = (quality |= 0x80) ? SANE_TRUE : SANE_FALSE;
871 mode->halftonePattern = _get_byte (data, 12);
872 mode->lineThreshold = _get_byte (data, 13);
873
874 DBG (DBG_info_scan, "cmdGetMode():\n");
875 DBG (DBG_info_scan, " resolution = %d\n", mode->resolution);
876 DBG (DBG_info_scan, " passes = %02x\n", mode->passes);
877 DBG (DBG_info_scan, " depth = %02x\n", mode->colorDepth);
878 DBG (DBG_info_scan, " color format = %02x\n", mode->colorFormat);
879 DBG (DBG_info_scan, " sharpen = %d\n", mode->sharpen);
880 DBG (DBG_info_scan, " skip calibration = %d\n", mode->skipShadingAnalysis);
881 DBG (DBG_info_scan, " fast infrared = %d\n", mode->fastInfrared);
882 DBG (DBG_info_scan, " halftone pattern = %d\n", mode->halftonePattern);
883 DBG (DBG_info_scan, " line threshold = %d\n", mode->lineThreshold);
884 #undef MODE_SIZE
885 }
886
887 /**
888 * Start a scan (SCSI SCAN command, code 0x1B, size byte = 0x01).\n
889 * There are four phases in a scan process. During each phase a limited number of
890 * commands is available. The phases are:\n
891 * 1. Calibration phase: make previously collected shading correction data available\n
892 * 2. Line-by-line scan & read phase\n
893 * 3. Output CCD-mask phase\n
894 * 4. Scan and output scan data phase\n
895 *
896 * The calibration phase is skipped if Pieusb_Mode.skipCalibration is set. If
897 * the scanner determines a calibration is necessary, a CHECK CONDIDITION response
898 * is returned. Available command during this phase:\n
899 * 1. sanei_pieusb_cmd_test_unit_ready()\n
900 * 2. sanei_pieusb_cmd_get_scanned_lines(): read shading correction lines\n
901 * 3. sanei_pieusb_cmd_stop_scan: abort scanning process\n
902 * 4. sanei_pieusb_cmd_get_gain_offset() : the settings are generated during the initialisation of this phase, so they are current\n
903 * 5. cmdSetSettings(): settings take effect in the next scan phase\n\n
904 * The line-by-line phase is only entered if Pieusb_Mode.div_10[0] bit 5 is
905 * set. It is not implemented.\n\n
906 * In the CCD-mask output phase the CCD-mask is read. Available command during this phase:\n
907 * 1. sanei_pieusb_cmd_test_unit_ready()\n
908 * 2. sanei_pieusb_cmd_get_ccd_mask()\n
909 * 3. sanei_pieusb_cmd_stop_scan: abort scanning process\n\n
910 * In the 'scan and output scan data' phase, the slide is scanned while data is
911 * read in the mean time. Available command during this phase:\n
912 * 1. sanei_pieusb_cmd_test_unit_ready()\n
913 * 2. sanei_pieusb_cmd_get_scanned_lines()\n
914 * 2. sanei_pieusb_cmd_get_parameters()\n
915 * 4. sanei_pieusb_cmd_stop_scan: abort scanning process\n
916 *
917 * @param device_number Device number
918 * @return Pieusb_Command_Status
919 */
920 void
sanei_pieusb_cmd_start_scan(SANE_Int device_number, struct Pieusb_Command_Status *status)921 sanei_pieusb_cmd_start_scan(SANE_Int device_number, struct Pieusb_Command_Status *status)
922 {
923 SANE_Byte command[SCSI_COMMAND_LEN];
924
925 DBG (DBG_info_scan, "sanei_pieusb_cmd_start_scan()\n");
926
927 _prep_scsi_cmd (command, SCSI_SCAN, 1);
928
929 status->pieusb_status = sanei_pieusb_command (device_number, command, NULL, 0);
930 }
931
932 /**
933 * Stop a scan started with sanei_pieusb_cmd_start_scan(). It issues a SCSI SCAN command,
934 * code 0x1B, with size byte = 0x00.
935 *
936 * @param device_number Device number
937 * @return Pieusb_Command_Status
938 */
939 void
sanei_pieusb_cmd_stop_scan(SANE_Int device_number, struct Pieusb_Command_Status *status)940 sanei_pieusb_cmd_stop_scan(SANE_Int device_number, struct Pieusb_Command_Status *status)
941 {
942 SANE_Byte command[SCSI_COMMAND_LEN];
943
944 DBG (DBG_info_scan, "sanei_pieusb_cmd_stop_scan()\n");
945
946 _prep_scsi_cmd (command, SCSI_SCAN, 0);
947
948 status->pieusb_status = sanei_pieusb_command (device_number, command, NULL, 0);
949 }
950
951 /**
952 * Set scan head to a specific position, depending on the value for mode:\n
953 * mode = 1: Returns the scan head to the resting position, after a short move
954 * forward. If this command is left out between two scans, the second scan is
955 * up-down-mirrored, and scanning starts where the proevious scan stopped.\n
956 * mode = 2: Resets the scan head an then moves it forward depending on 'size',
957 * but it is a bit unpredictable to what position. The scanner may attempt to
958 * move the head past its physical end position. The mode is not implemented.\n
959 * mode = 3: This command positions the scan head to the start of the slide.\n
960 * mode = 4 or 5: The command forwards (4) or retreats (5) the scan head the
961 * given amount of steps (in size).\n
962 * The SCSI code is 0xD2, there is no related command name.
963 *
964 * @param device_number Device number
965 * @param mode
966 * @param size
967 * @return Pieusb_Command_Status
968 */
969 void
sanei_pieusb_cmd_set_scan_head(SANE_Int device_number, SANE_Int mode, SANE_Int steps, struct Pieusb_Command_Status *status)970 sanei_pieusb_cmd_set_scan_head(SANE_Int device_number, SANE_Int mode, SANE_Int steps, struct Pieusb_Command_Status *status)
971 {
972 SANE_Byte command[SCSI_COMMAND_LEN];
973 #define SCAN_HEAD_SIZE 4
974 SANE_Int size = SCAN_HEAD_SIZE;
975 SANE_Byte data[SCAN_HEAD_SIZE];
976
977 DBG (DBG_info_scan, "sanei_pieusb_cmd_set_scan_head()\n");
978
979 _prep_scsi_cmd (command, SCSI_SET_SCAN_HEAD, size);
980
981 /* Code data */
982 memset (data, '\0', size);
983 switch (mode) {
984 case 1:
985 data[0] = 2;
986 break;
987 case 2:
988 DBG (DBG_error, "sanei_pieusb_cmd_set_scan_head() mode 2 unreliable, possibly dangerous\n");
989 status->pieusb_status = PIEUSB_STATUS_INVAL;
990 return;
991 case 3:
992 data[0] = 8;
993 break;
994 case 4:
995 data[0] = 0; /* forward */
996 data[2] = (steps>>8) & 0xFF;
997 data[3] = steps & 0xFF;
998 break;
999 case 5:
1000 data[0] = 1; /* backward */
1001 data[2] = (steps>>8) & 0xFF;
1002 data[3] = steps & 0xFF;
1003 break;
1004 }
1005
1006 status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
1007 #undef SCAN_HEAD_SIZE
1008 }
1009
1010 /**
1011 * Get internal scanner settings which have resulted from an auto-calibration
1012 * procedure. This procedure only runs when calibrating (Scan phase 1), so the
1013 * data returned are relatively static.\n
1014 * The SCSI code is 0xD7, there is no related command name.
1015 *
1016 * @param device_number Device number
1017 * @param settings Settings for gain and offset for the four colors RGBI
1018 * @return Pieusb_Command_Status
1019 * @see Pieusb_Settings
1020 */
1021 void
sanei_pieusb_cmd_get_gain_offset(SANE_Int device_number, struct Pieusb_Settings* settings, struct Pieusb_Command_Status *status)1022 sanei_pieusb_cmd_get_gain_offset(SANE_Int device_number, struct Pieusb_Settings* settings, struct Pieusb_Command_Status *status)
1023 {
1024 SANE_Byte command[SCSI_COMMAND_LEN];
1025 #define GAIN_OFFSET_SIZE 103
1026 SANE_Int size = GAIN_OFFSET_SIZE;
1027 SANE_Byte data[GAIN_OFFSET_SIZE];
1028 int k;
1029 SANE_Byte val[3];
1030
1031 DBG (DBG_info_scan, "sanei_pieusb_cmd_get_gain_offset()\n");
1032
1033 _prep_scsi_cmd (command, SCSI_READ_GAIN_OFFSET, size);
1034
1035 memset (data, '\0', size);
1036 status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
1037 if (status->pieusb_status != PIEUSB_STATUS_GOOD) {
1038 return;
1039 }
1040
1041 /* Decode data received */
1042 _get_shorts (settings->saturationLevel, data+54, 3);
1043 _get_shorts (settings->exposureTime, data+60, 3);
1044 _copy_bytes (val, data+66, 3);
1045 for (k = 0; k < 3; k++) settings->offset[k] = val[k];
1046 _copy_bytes (val, data+72, 3);
1047 for (k = 0; k < 3; k++) settings->gain[k] = val[k];
1048 settings->light = _get_byte (data, 75);
1049 settings->exposureTime[3] = _get_short (data, 98);
1050 settings->offset[3] = _get_byte (data, 100);
1051 settings->gain[3] = _get_byte (data, 102);
1052
1053 DBG (DBG_info, "sanei_pieusb_cmd_get_gain_offset() set:\n");
1054 DBG (DBG_info, " saturationlevels = %d-%d-%d\n", settings->saturationLevel[0], settings->saturationLevel[1], settings->saturationLevel[2]);
1055 DBG (DBG_info, " ---\n");
1056 DBG (DBG_info, " exposure times = %d-%d-%d-%d\n", settings->exposureTime[0], settings->exposureTime[1], settings->exposureTime[2], settings->exposureTime[3]);
1057 DBG (DBG_info, " gain = %d-%d-%d-%d\n", settings->gain[0], settings->gain[1], settings->gain[2], settings->gain[3]);
1058 DBG (DBG_info, " offset = %d-%d-%d-%d\n", settings->offset[0], settings->offset[1], settings->offset[2], settings->offset[3]);
1059 DBG (DBG_info, " light = %02x\n", settings->light);
1060 DBG (DBG_info, " double times = %02x\n", settings->doubleTimes);
1061 DBG (DBG_info, " extra entries = %02x\n", settings->extraEntries);
1062 #undef GAIN_OFFSET_SIZE
1063 }
1064
1065
1066 /**
1067 * Set internal scanner settings such as gain and offset.\n
1068 * There are two effective moments for this command:\n
1069 * 1. For a scan without calibration phase: before the sanei_pieusb_cmd_start_scan() command;
1070 * 2. For a sccan with calibration phase: before (or during) reading the shading reference data.
1071 * The SCSI code is 0xDC, there is no related command name.
1072 *
1073 * @param device_number Device number
1074 * @param settings Settings for gain and offset for the four colors RGBI
1075 * @return Pieusb_Command_Status
1076 * @see Pieusb_Settings
1077 */
1078 void
sanei_pieusb_cmd_set_gain_offset(SANE_Int device_number, struct Pieusb_Settings* settings, struct Pieusb_Command_Status *status)1079 sanei_pieusb_cmd_set_gain_offset(SANE_Int device_number, struct Pieusb_Settings* settings, struct Pieusb_Command_Status *status)
1080 {
1081 SANE_Byte command[SCSI_COMMAND_LEN];
1082 #define GAIN_OFFSET_SIZE 29
1083 SANE_Int size = GAIN_OFFSET_SIZE;
1084 SANE_Byte data[GAIN_OFFSET_SIZE];
1085 int k;
1086 SANE_Byte val[3];
1087
1088 DBG (DBG_info_scan, "sanei_pieusb_cmd_set_gain_offset()\n");
1089
1090 _prep_scsi_cmd (command, SCSI_WRITE_GAIN_OFFSET, size);
1091
1092 DBG (DBG_info, "sanei_pieusb_cmd_set_gain_offset() set:\n");
1093 DBG (DBG_info, " exposure times = %d-%d-%d-%d\n", settings->exposureTime[0], settings->exposureTime[1], settings->exposureTime[2], settings->exposureTime[3]);
1094 DBG (DBG_info, " gain = %d-%d-%d-%d\n", settings->gain[0], settings->gain[1], settings->gain[2], settings->gain[3]);
1095 DBG (DBG_info, " offset = %d-%d-%d-%d\n", settings->offset[0], settings->offset[1], settings->offset[2], settings->offset[3]);
1096 DBG (DBG_info, " light = %02x\n", settings->light);
1097 DBG (DBG_info, " double times = %02x\n", settings->doubleTimes);
1098 DBG (DBG_info, " extra entries = %02x\n", settings->extraEntries);
1099
1100 /* Code data */
1101 memset (data, '\0', size);
1102 _set_shorts (settings->exposureTime, data, 3);
1103 for (k = 0; k < 3; k++) {
1104 val[k] = settings->offset[k];
1105 }
1106 _copy_bytes (data + 6, val, 3);
1107 for (k = 0; k < 3; k++) {
1108 val[k] = settings->gain[k];
1109 }
1110 _copy_bytes (data + 12, val, 3);
1111 _set_byte (settings->light, data, 15);
1112 _set_byte (settings->extraEntries, data, 16);
1113 _set_byte (settings->doubleTimes, data, 17);
1114 _set_short (settings->exposureTime[3], data, 18);
1115 _set_byte (settings->offset[3], data, 20);
1116 _set_byte (settings->gain[3], data, 22);
1117 /*
1118 * pieusb-get_gain_offset:
1119 * 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1120 * 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1121 * 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1122 * 00000030: a9 00 88 00 b1 00 00 00 00 00 00 00 04 10 04 10 )...1...........
1123 * 00000040: 04 10 53 4f 6e 00 00 00 2e 21 21 05 04 10 df 2d ..SOn....!!..._-
1124 * 00000050: a3 5c e7 f2 a1 2c b3 c4 42 df 32 42 eb 82 8e e0 #\gr!,3DB_2Bk..`
1125 * 00000060: 87 be 04 10 4f 00 2c .>..O.,
1126 *
1127 * cyberview:
1128 * 00000000: 65 22 57 18 19 19 - exposure time RGB
1129 * 00000006: 51 4e 6a - offset RGB
1130 * 00000009: 00 00 00
1131 * 0000000c: 21 21 21 - gain RGB
1132 * 0000000f: 05 - light
1133 * 00000010: 01 - extra entries
1134 * 00000011: 00 - double times
1135 * 00000012: 04 10 - exposure time I
1136 * 00000014: 4e 00 - offset I
1137 * 00000016: 2a - gain I
1138 * 00000017: 00 00 00 00 00 00
1139 *
1140 * pieusb:
1141 * 00000000: 04 10 04 10 04 10 - exposure time RGB
1142 * 00000006: 53 4f 6e - offset RGB
1143 * 00000009: 00 00 00
1144 * 0000000c: 2e 21 21 - gain RGB
1145 * 0000000f: 05 - light
1146 * 00000010: 00 - extra entries
1147 * 00000011: 00 - double times
1148 * 00000012: 04 10 - exposure time I
1149 * 00000014: 4f 00 - offset I
1150 * 00000016: 2c - gain I
1151 * 00000017: 00 00 00 00 00 00
1152 */
1153
1154 status->pieusb_status = sanei_pieusb_command(device_number, command, data, size);
1155 #undef GAIN_OFFSET_SIZE
1156 }
1157
1158 /**
1159 * Get scanner state information: button pushed,
1160 * warming up, scanning.
1161 *
1162 * @param device_number Device number
1163 * @param state State information
1164 * @return Pieusb_Command_Status
1165 */
1166 void
sanei_pieusb_cmd_read_state(SANE_Int device_number, struct Pieusb_Scanner_State* state, struct Pieusb_Command_Status *status)1167 sanei_pieusb_cmd_read_state(SANE_Int device_number, struct Pieusb_Scanner_State* state, struct Pieusb_Command_Status *status)
1168 {
1169 SANE_Byte command[SCSI_COMMAND_LEN];
1170 #define GET_STATE_SIZE 12
1171 SANE_Byte data[GET_STATE_SIZE];
1172 SANE_Int size = GET_STATE_SIZE;
1173
1174 /* Execute READ STATUS command */
1175 DBG (DBG_info_scan, "sanei_pieusb_cmd_read_state()\n");
1176
1177 _prep_scsi_cmd (command, SCSI_READ_STATE, size);
1178
1179 memset (data, '\0', size);
1180 status->pieusb_status = sanei_pieusb_command (device_number, command, data, size);
1181
1182 if (status->pieusb_status == PIEUSB_STATUS_WARMING_UP
1183 || status->pieusb_status == PIEUSB_STATUS_DEVICE_BUSY) {
1184 data[5] = 1;
1185 status->pieusb_status = PIEUSB_STATUS_GOOD;
1186 }
1187 /* Decode data received */
1188 state->buttonPushed = _get_byte(data, 0);
1189 state->warmingUp = _get_byte(data, 5);
1190 state->scanning = _get_byte(data, 6);
1191 /* state->busy = _get_byte(data, 8); */
1192 DBG (DBG_info_scan, "sanei_pieusb_cmd_read_state(): button %d, warmingUp %d, scanning %d, busy? %d\n", state->buttonPushed, state->warmingUp, state->scanning, _get_byte(data, 8));
1193 #undef GET_STATE_SIZE
1194 }
1195
1196 /**
1197 * Prepare SCSI_COMMAND_LEN-byte command array with command code and size value
1198 *
1199 * @param command
1200 * @param code
1201 * @param size
1202 */
1203 static void
_prep_scsi_cmd(SANE_Byte* command, SANE_Byte code, SANE_Word size)1204 _prep_scsi_cmd(SANE_Byte* command, SANE_Byte code, SANE_Word size)
1205 {
1206 memset(command, '\0', SCSI_COMMAND_LEN);
1207 command[0] = code;
1208 command[3] = (size>>8) & 0xFF; /* lsb first */
1209 command[4] = size & 0xFF;
1210 }
1211