1 /**********************************************************************
2 * Minolta Dimage V digital camera communication library *
3 * Copyright 2000,2001 Gus Hartmann *
4 * *
5 * This program is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License as *
7 * published by the Free Software Foundation; either version 2 of *
8 * the License, or (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public *
16 * License along with this program; if not, write to the *
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
19 * *
20 **********************************************************************/
21
22 /* $Id$ */
23
24 #include "config.h"
25
26 #include <stdio.h>
27
28 #include "dimagev.h"
29
30 #define GP_MODULE "dimagev"
31
32 /* This is the parent function, who calls most of the functions below.
33 It returns GP_ERROR if it cannot get the camera data, and GP_OK otherwise.
34 The subroutines will print out more detained information should they fail.
35 */
dimagev_get_camera_data(dimagev_t * dimagev)36 int dimagev_get_camera_data(dimagev_t *dimagev) {
37 dimagev_packet *p, *raw;
38 unsigned char char_buffer;
39
40 /* Check the device. */
41 if ( dimagev->dev == NULL ) {
42 GP_DEBUG( "dimagev_get_camera_data::device not valid");
43 return GP_ERROR_BAD_PARAMETERS;
44 }
45
46 /* Let's say hello and get the current status. */
47 if ( ( p = dimagev_make_packet(DIMAGEV_GET_DATA, 1, 0)) == NULL ) {
48 GP_DEBUG( "dimagev_get_camera_data::unable to allocate packet");
49 return GP_ERROR_NO_MEMORY;
50 }
51
52 if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) {
53 GP_DEBUG( "dimagev_get_camera_data::unable to write packet");
54 free(p);
55 return GP_ERROR_IO;
56 } else if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
57 GP_DEBUG( "dimagev_get_camera_data::no response from camera");
58 free(p);
59 return GP_ERROR_IO;
60 }
61
62 free(p);
63
64 switch ( char_buffer ) {
65 case DIMAGEV_ACK:
66 break;
67 case DIMAGEV_NAK:
68 GP_DEBUG( "dimagev_get_camera_data::camera did not acknowledge transmission");
69 return GP_ERROR_IO;
70 case DIMAGEV_CAN:
71 GP_DEBUG( "dimagev_get_camera_data::camera cancels transmission");
72 return GP_ERROR_IO;
73 default:
74 GP_DEBUG( "dimagev_get_camera_data::camera responded with unknown value %x", char_buffer);
75 return GP_ERROR_IO;
76 }
77
78 if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) {
79 GP_DEBUG( "dimagev_get_camera_data::unable to read packet");
80 return GP_ERROR_IO;
81 }
82
83 char_buffer = DIMAGEV_EOT;
84 if ( gp_port_write(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
85 GP_DEBUG( "dimagev_get_camera_data::unable to send EOT");
86 free(p);
87 return GP_ERROR_IO;
88 }
89
90 if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
91 GP_DEBUG( "dimagev_get_camera_data::no response from camera");
92 free(p);
93 return GP_ERROR_IO;
94 }
95
96 switch ( char_buffer ) {
97 case DIMAGEV_ACK:
98 break;
99 case DIMAGEV_NAK:
100 GP_DEBUG( "dimagev_get_camera_data::camera did not acknowledge transmission");
101 free(p);
102 return GP_ERROR_IO;
103 case DIMAGEV_CAN:
104 GP_DEBUG( "dimagev_get_camera_data::camera cancels transmission");
105 free(p);
106 return GP_ERROR_IO;
107 default:
108 GP_DEBUG( "dimagev_get_camera_data::camera responded with unknown value %x", char_buffer);
109 free(p);
110 return GP_ERROR_IO;
111 }
112
113 if ( ( raw = dimagev_strip_packet(p) ) == NULL ) {
114 GP_DEBUG( "dimagev_get_camera_data::unable to strip data packet");
115 free(p);
116 return GP_ERROR;
117 }
118
119 if ( ( dimagev->data = dimagev_import_camera_data(raw->buffer)) == NULL ) {
120 GP_DEBUG( "dimagev_get_camera_data::unable to read camera data");
121 free(raw);
122 free(p);
123 return GP_ERROR;
124 }
125
126 /* Sure it *should* get freed automagically, but why take the risk? */
127 free(p);
128 free(raw);
129
130 return GP_OK;
131 }
132
133 /* This function sends the contents of a dimagev_data_t to the current camera.
134 This allows many changes to be made (e.g. entering host mode and record
135 mode) while only sending a single set_data command.
136 */
dimagev_send_data(dimagev_t * dimagev)137 int dimagev_send_data(dimagev_t *dimagev) {
138 dimagev_packet *p;
139 unsigned char *export_data, char_buffer;
140
141
142 if ( dimagev == NULL ) {
143 GP_DEBUG( "dimagev_send_data::unable to use NULL dimagev_t");
144 return GP_ERROR_BAD_PARAMETERS;
145 }
146
147 if ( ( export_data = dimagev_export_camera_data(dimagev->data) ) == NULL ) {
148 GP_DEBUG( "dimagev_send_data::unable to export camera data");
149 return GP_ERROR;
150 }
151
152 dimagev_dump_camera_data(dimagev->data);
153
154 if ( ( p = dimagev_make_packet(DIMAGEV_SET_DATA, 1, 0) ) == NULL ) {
155 GP_DEBUG( "dimagev_send_data::unable to create set_data packet");
156 free(export_data);
157 return GP_ERROR_NO_MEMORY;
158 }
159
160 if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) {
161 GP_DEBUG( "dimagev_send_data::unable to send set_data packet");
162 free(p);
163 free(export_data);
164 return GP_ERROR_IO;
165 } else if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
166 GP_DEBUG( "dimagev_send_data::no response from camera - trying to send NAK");
167 free(p);
168 free(export_data);
169 return GP_ERROR_IO;
170 }
171
172 free(p);
173
174 switch ( char_buffer ) {
175 case DIMAGEV_ACK:
176 break;
177 case DIMAGEV_NAK:
178 GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission");
179 free(export_data);
180 return GP_ERROR_IO;
181 case DIMAGEV_CAN:
182 GP_DEBUG( "dimagev_send_data::camera cancels transmission");
183 free(export_data);
184 return GP_ERROR_IO;
185 default:
186 GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer);
187 free(export_data);
188 return GP_ERROR_IO;
189 }
190
191 if ( ( p = dimagev_make_packet(export_data, 9, 1) ) == NULL ) {
192 GP_DEBUG( "dimagev_send_data::unable to create set_data packet");
193 free(export_data);
194 return GP_ERROR_NO_MEMORY;
195 }
196
197 free(export_data);
198
199 if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) {
200 GP_DEBUG( "dimagev_send_data::unable to send data packet");
201 free(p);
202 return GP_ERROR_IO;
203 }
204
205 free(p);
206
207 if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
208 GP_DEBUG( "dimagev_send_data::no response from camera");
209 return GP_ERROR_IO;
210 }
211
212 switch ( char_buffer ) {
213 case DIMAGEV_ACK:
214 break;
215 case DIMAGEV_NAK:
216 GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission");
217 return GP_ERROR_IO;
218 case DIMAGEV_CAN:
219 GP_DEBUG( "dimagev_send_data::camera cancels transmission");
220 return GP_ERROR_IO;
221 default:
222 GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer);
223 return GP_ERROR_IO;
224 }
225
226
227 char_buffer = DIMAGEV_EOT;
228 if ( gp_port_write(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
229 GP_DEBUG( "dimagev_send_data::unable to send EOT");
230 return GP_ERROR_IO;
231 }
232
233 if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
234 GP_DEBUG( "dimagev_send_data::no response from camera");
235 return GP_ERROR_IO;
236 }
237
238 switch ( char_buffer ) {
239 case DIMAGEV_ACK:
240 break;
241 case DIMAGEV_NAK:
242 GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission");
243 return GP_ERROR_IO;
244 case DIMAGEV_CAN:
245 GP_DEBUG( "dimagev_send_data::camera cancels transmission");
246 return GP_ERROR_IO;
247 default:
248 GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer);
249 return GP_ERROR_IO;
250 }
251
252 if ( sleep(3) != 0 ) {
253 GP_DEBUG( "dimagev_send_data::sleep() returned non-zero value");
254 }
255
256 return GP_OK;
257 }
258
259 /* This function populates and retuens a dimagev_data_t with the values
260 contained inside an array of bytes, as returned by the Dimage V. See
261 the description of these fields in the appropriate header file for
262 more information on the bit-packing done here.
263 */
dimagev_import_camera_data(unsigned char * raw_data)264 dimagev_data_t *dimagev_import_camera_data(unsigned char *raw_data) {
265 dimagev_data_t *processed_data;
266
267 if ( raw_data == NULL ) {
268 return NULL;
269 }
270
271 if ( ( processed_data = malloc(sizeof(dimagev_data_t)) ) == NULL ) {
272 return NULL;
273 }
274
275 /* They really pack those bit fields. */
276 processed_data->host_mode = ( raw_data[0] & 0x80) >> 7;
277 processed_data->exposure_valid = (raw_data[0] & 0x40 ) >> 6;
278 processed_data->date_valid = (raw_data[0] & 0x20 ) >> 5;
279 processed_data->self_timer_mode = (raw_data[0] & 0x10 ) >> 4;
280 processed_data->flash_mode = ( raw_data[0] & 0x0C ) >> 2;
281 processed_data->quality_setting = ( raw_data[0] & 0x02 ) >> 1;
282 processed_data->play_rec_mode = (raw_data[0] & 0x01 );
283 processed_data->year = dimagev_bcd_to_decimal(raw_data[1]);
284 processed_data->month = dimagev_bcd_to_decimal(raw_data[2]);
285 processed_data->day = dimagev_bcd_to_decimal(raw_data[3]);
286 processed_data->hour = dimagev_bcd_to_decimal(raw_data[4]);
287 processed_data->minute = dimagev_bcd_to_decimal(raw_data[5]);
288 processed_data->second = dimagev_bcd_to_decimal(raw_data[6]);
289 processed_data->exposure_correction = raw_data[7];
290 processed_data->valid = ( raw_data[8] & 0x80) >> 7;
291 processed_data->id_number = ( raw_data[8] & 0x7F);
292
293 return processed_data;
294 }
295
dimagev_export_camera_data(dimagev_data_t * good_data)296 unsigned char *dimagev_export_camera_data(dimagev_data_t *good_data) {
297 unsigned char *export_data;
298
299 if ( ( export_data = malloc(9) ) == NULL ) {
300 perror("dimagev_export_camera_data::unable to allocate buffer");
301 return NULL;
302 }
303
304 export_data[0] = (unsigned char) 0;
305 export_data[0] = export_data[0] | ( ( ( good_data->host_mode ) << 7 ) & 0x80 );
306 export_data[0] = export_data[0] | ( ( ( good_data->exposure_valid ) << 6 ) & 0x40 );
307 export_data[0] = export_data[0] | ( ( ( good_data->date_valid ) << 5 ) & 0x20 );
308 export_data[0] = export_data[0] | ( ( ( good_data->self_timer_mode ) << 4 ) & 0x10 );
309 export_data[0] = export_data[0] | ( ( ( good_data->flash_mode ) << 2 ) & 0x0C );
310 export_data[0] = export_data[0] | ( ( ( good_data->quality_setting ) << 1 ) & 0x02 );
311 export_data[0] = export_data[0] | ( ( ( good_data->play_rec_mode )) & 0x01 );
312 export_data[1] = (unsigned char) 0;
313 export_data[1] = dimagev_decimal_to_bcd(good_data->year);
314 export_data[2] = (unsigned char) 0;
315 export_data[2] = dimagev_decimal_to_bcd(good_data->month);
316 export_data[3] = (unsigned char) 0;
317 export_data[3] = dimagev_decimal_to_bcd(good_data->day);
318 export_data[4] = (unsigned char) 0;
319 export_data[4] = dimagev_decimal_to_bcd(good_data->hour);
320 export_data[5] = (unsigned char) 0;
321 export_data[5] = dimagev_decimal_to_bcd(good_data->minute);
322 export_data[6] = (unsigned char) 0;
323 export_data[6] = dimagev_decimal_to_bcd(good_data->second);
324 export_data[7] = (unsigned char) 0;
325 export_data[7] = good_data->exposure_correction;
326 export_data[8] = (unsigned char) 0;
327 export_data[8] = export_data[8] & ( ( ( good_data->valid ) << 7 ) & 0x80 );
328 export_data[8] = export_data[8] & ( ( ( good_data->id_number ) ) & 0x7F );
329
330 return export_data;
331 }
332
dimagev_dump_camera_data(dimagev_data_t * data)333 void dimagev_dump_camera_data(dimagev_data_t *data) {
334 GP_DEBUG( "========= Begin Camera Data =========");
335 GP_DEBUG( "Host mode: %s ( %d )", data->host_mode != (unsigned char) 0 ? "Host mode" : "Camera mode", data->host_mode);
336 GP_DEBUG( "Exposure valid: %s ( %d )", data->exposure_valid != (unsigned char) 0 ? "Valid" : "Not Valid", data->exposure_valid);
337 GP_DEBUG( "Exposure correction: %d", (signed char)data->exposure_correction);
338 GP_DEBUG( "Date valid: %s ( %d )", data->date_valid != (unsigned char) 0 ? "Valid" : "Not Valid", data->exposure_valid);
339 GP_DEBUG( "Self timer mode: %s ( %d )", data->self_timer_mode != (unsigned char) 0 ? "Yes" : "No", data->self_timer_mode);
340 GP_DEBUG( "Flash mode: ");
341
342 switch ( data->flash_mode ) {
343 case 0:
344 GP_DEBUG( "\tAuto ( 0 )");
345 break;
346 case 1:
347 GP_DEBUG( "\tForce Flash ( 1 )");
348 break;
349 case 2:
350 GP_DEBUG( "\tProhibit Flash ( 2 )");
351 break;
352 default:
353 GP_DEBUG( "\tInvalid mode for flash ( %d )", data->flash_mode);
354 break;
355 }
356
357 GP_DEBUG( "Quality mode: %s ( %d )", data->quality_setting ? "High" : "Low", data->quality_setting);
358 GP_DEBUG( "Play or Record mode: %s ( %d )", data->play_rec_mode != (unsigned char) 0 ? "Record" : "Play", data->play_rec_mode);
359 GP_DEBUG( "Date: %02d/%02d/%02d %02d:%02d:%02d", data->year, data->month, data->day, data->hour, data->minute, data->second);
360 GP_DEBUG( "Card ID Valid: %s ( %d )", data->valid != (unsigned char) 0 ? "Valid" : "Invalid", data->valid);
361 GP_DEBUG( "Card ID Data: %02x", data->id_number);
362 GP_DEBUG( "========== End Camera Data ==========");
363
364 return;
365 }
366
367 /* This function gets the current system time, sets the contents of the current
368 dimagev->data struct appropriately, and then sends the data.
369 */
dimagev_set_date(dimagev_t * dimagev)370 int dimagev_set_date(dimagev_t *dimagev) {
371 struct tm *this_time;
372 time_t now;
373
374 if ( dimagev == NULL ) {
375 return GP_ERROR_BAD_PARAMETERS;
376 }
377
378 if ( ( now = time(NULL) ) < 0 ) {
379 GP_DEBUG( "dimagev_set_date::unable to get system time");
380 return GP_ERROR;
381 }
382
383 if ( ( this_time = localtime(&now) ) == NULL ) {
384 GP_DEBUG( "dimagev_set_date::unable to convert system time to local time");
385 return GP_ERROR;
386 }
387
388 GP_DEBUG( "Setting clock to %02d/%02d/%02d %02d:%02d:%02d", this_time->tm_year % 100, ( this_time->tm_mon + 1 ), this_time->tm_mday, this_time->tm_hour, this_time->tm_min, this_time->tm_sec);
389
390 dimagev->data->date_valid = (unsigned char) 1;
391 dimagev->data->year = (unsigned char) ( this_time->tm_year % 100 );
392 dimagev->data->month = (unsigned char) ( this_time->tm_mon + 1 );
393 dimagev->data->day = (unsigned char) this_time->tm_mday;
394 dimagev->data->hour = (unsigned char) this_time->tm_hour;
395 dimagev->data->minute = (unsigned char) this_time->tm_min;
396 dimagev->data->second = (unsigned char) this_time->tm_sec;
397
398 if ( dimagev_send_data(dimagev) < GP_OK ) {
399 GP_DEBUG( "dimagev_set_date::unable to set time");
400 return GP_ERROR_IO;
401 }
402
403 /* So we don't set this date again later by mistake. */
404 dimagev->data->date_valid = (unsigned char) 0;
405
406 if ( dimagev_send_data(dimagev) < GP_OK ) {
407 GP_DEBUG( "dimagev_set_date::unable to set time");
408 return GP_ERROR_IO;
409 }
410
411 return GP_OK;
412 }
413