diff --git a/camlibs/digita/.cvsignore b/camlibs/digita/.cvsignore new file mode 100644 index 000000000..156dc017e --- /dev/null +++ b/camlibs/digita/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.deps +*.lo +.libs +*.la diff --git a/camlibs/digita/Makefile.am b/camlibs/digita/Makefile.am new file mode 100644 index 000000000..ccf4b2f3f --- /dev/null +++ b/camlibs/digita/Makefile.am @@ -0,0 +1,11 @@ +camlibdir = $(prefix)/lib/gphoto2 +camlib_LTLIBRARIES = libgphoto2_digita.la + +CFLAGS = @CFLAGS@ -g `gpio-config --cflags` +LDFLAGS = @LDFLAGS@ -g `gpio-config --libs` +INCLUDES = -I$(top_srcdir)/include + +libgphoto2_digita_la_SOURCES = digita.c serial.c usb.c commands.c digita.h + +libgphoto2_digita_la_LDFLAGS = -version-info 0:0:0 + diff --git a/camlibs/digita/commands.c b/camlibs/digita/commands.c new file mode 100644 index 000000000..24e67dfe3 --- /dev/null +++ b/camlibs/digita/commands.c @@ -0,0 +1,190 @@ +/* + * commands.c + * + * Command set for the digita cameras + * + * Copyright 1999-2000 Johannes Erdfelt + */ + +#include +#include +#include +#include +#include + +#include "digita.h" + +#include + +int digita_num_pictures = 0; +struct file_item *digita_file_list = NULL; + +void build_command(struct digita_command *cmd, int length, short command) +{ + /* Length is the sizeof the digita_command minus the length */ + /* parameter, plus whatever other data we send */ + cmd->length = htonl(sizeof(struct digita_command) - + sizeof(unsigned int) + length); + cmd->unknown = cmd->status = 0; + cmd->command = htons(command); +} + +struct storage_status { + struct digita_command cmd; + + unsigned int takencount; + unsigned int availablecount; + int rawcount; +}; + +int digita_get_storage_status(struct digita_device *dev, int *taken, + int *available, int *rawcount) +{ + struct digita_command cmd; + struct storage_status ss; + int ret; + + build_command(&cmd, 0, DIGITA_GET_STORAGE_STATUS); + + ret = digita_send(dev, &cmd, sizeof(cmd)); + if (ret < 0) { + fprintf(stderr, "digita_get_storage_status: error sending command\n"); + return -1; + } + + ret = digita_read(dev, (unsigned char *)&ss, sizeof(ss)); + if (ret < 0) { + fprintf(stderr, "digita_get_storage_status: error getting count\n"); + return -1; + } + + if (taken) + *taken = ntohl(ss.takencount); + if (available) + *available = ntohl(ss.availablecount); + if (rawcount) + *rawcount = ntohl(ss.rawcount); + + return 0; +} + +int digita_get_file_list(struct digita_device *dev) +{ + struct digita_command cmd; + struct get_file_list gfl; + char *buffer; + int ret, taken, buflen; + + if (digita_get_storage_status(dev, &taken, NULL, NULL) < 0) + return -1; + + digita_num_pictures = taken; + + buflen = (taken * sizeof(struct file_item)) + sizeof(cmd) + 4; + buffer = malloc(buflen); + if (!buffer) { + fprintf(stderr, "digita_get_file_list: error allocating %d +bytes\n", buflen); + return -1; + } + + build_command(&gfl.cmd, sizeof(gfl) - sizeof(gfl.cmd), DIGITA_GET_FILE_LIST); + gfl.listorder = htonl(1); + + ret = digita_send(dev, (void *)&gfl, sizeof(gfl)); + if (ret < 0) { + fprintf(stderr, "digita_get_file_list: error sending command\n"); + return -1; + } + + ret = digita_read(dev, (void *)buffer, buflen); + if (ret < 0) { + fprintf(stderr, "digita_get_file_list: error receiving data\n"); + return -1; + } + + if (digita_file_list) + free(digita_file_list); + + digita_file_list = malloc(taken * sizeof(struct file_item)); + if (!digita_file_list) { + fprintf(stderr, "digita_get_file_list: error allocating file_list memory\n"); + return -1; + } + + memcpy(digita_file_list, buffer + sizeof(cmd) + 4, taken * sizeof(struct file_item)); + + free(buffer); + + return 0; +} + +#define GFD_BUFSIZE 19432 +int digita_get_file_data(struct digita_device *dev, int thumbnail, + struct filename *filename, struct partial_tag *tag, void *buffer) +{ + struct get_file_data_send gfds; + struct get_file_data_receive *gfdr; + int ret; + char *tbuf; + + build_command(&gfds.cmd, sizeof(gfds) - sizeof(gfds.cmd), DIGITA_GET_FILE_DATA); + + memcpy(&gfds.fn, filename, sizeof(gfds.fn)); + memcpy(&gfds.tag, tag, sizeof(gfds.tag)); + gfds.dataselector = htonl(thumbnail); + + tbuf = malloc(GFD_BUFSIZE + sizeof(*gfdr)); + if (!tbuf) { + fprintf(stderr, "digita_get_file_data: unable to allocate %d bytes\n", + GFD_BUFSIZE + sizeof(*gfdr)); + + return -1; + } + gfdr = (struct get_file_data_receive *)tbuf; + + ret = digita_send(dev, &gfds, sizeof(gfds)); + if (ret < 0) { + fprintf(stderr, "digita_get_file_data: error sending command\n"); + return -1; + } + + ret = digita_read(dev, gfdr, GFD_BUFSIZE + sizeof(*gfdr)); + if (ret < 0) { + fprintf(stderr, "digita_get_file_data: error reading data\n"); + return -1; + } + + memcpy(buffer, tbuf + sizeof(*gfdr), ntohl(gfdr->tag.length)); + memcpy(tag, &gfdr->tag, sizeof(*tag)); + + free(tbuf); + + return 0; +} + +int digita_delete_picture(struct digita_device *dev, struct filename *filename) +{ + struct erase_file ef; + struct digita_command response; + int ret; + + build_command(&ef.cmd, sizeof(ef) - sizeof(ef.cmd), DIGITA_ERASE_FILE); + + memcpy(&ef.fn, filename, sizeof(ef.fn)); + + ret = digita_send(dev, (unsigned char *)&ef, sizeof(ef)); + if (ret < 0) { + fprintf(stderr, "error sending command\n"); + return -1; + } + + ret = digita_read(dev, (unsigned char *)&response, sizeof(response)); + if (ret < 0) { + fprintf(stderr, "error reading reply\n"); + return -1; + } + + return 0; +} + diff --git a/camlibs/digita/digita.c b/camlibs/digita/digita.c new file mode 100644 index 000000000..c1adc71a7 --- /dev/null +++ b/camlibs/digita/digita.c @@ -0,0 +1,346 @@ +/* + * digita.c + * + * Copyright (c) 1999-2000 Johannes Erdfelt + * Copyright (c) 1999-2000 VA Linux Systems + */ + +#include +#include +#include +#include +#include + +#include + +#include "digita.h" + +#include + +static int debug = 0; +static struct digita_device *dev = NULL; + +int (*digita_send)(struct digita_device *dev, void *buffer, int buflen) = NULL; +int (*digita_read)(struct digita_device *dev, void *buffer, int buflen) = NULL; + +int camera_id(char *id) +{ + strcpy(id, "digita"); + + return GP_OK; +} + +int camera_abilities(CameraAbilities *abilities, int *count) +{ + *count = 1; + + strcpy(abilities[0].model, "Kodak DC260"); + abilities[0].serial = 1; + abilities[0].parallel = 0; + abilities[0].usb = 1; + abilities[0].ieee1394 = 0; + abilities[0].speed[0] = 57600; + abilities[0].speed[1] = 0; + abilities[0].capture = 1; + abilities[0].config = 0; + abilities[0].file_delete = 1; + abilities[0].file_preview = 1; + abilities[0].file_put = 0; + + return GP_OK; +} + +int camera_init(CameraInit *init) +{ + debug = init->debug; + + if (debug) + printf("digita: Initializing the camera\n"); + + if (dev) { + gpio_close(dev); + gpio_open(dev); + } + + dev = digita_usb_open(); + +/* + if (camera_type == GPHOTO_CAMERA_USB) + dev = digita_usb_open(); + else + dev = digita_serial_open(); +*/ + + return dev ? GP_OK : GP_ERROR; +} + +int camera_exit(void) +{ + return GP_OK; +} + +int camera_folder_list(char *folder_name, CameraFolderInfo *list) +{ + return GP_OK; +} + +int camera_folder_set(char *folder_name) +{ + return GP_OK; +} + +int camera_file_count(void) +{ + int taken; + + printf("digita: camera_file_count\n"); + + if (digita_get_storage_status(dev, &taken, NULL, NULL) < 0) + return 0; + + if (digita_get_file_list(dev) < 0) + return 0; + + return taken; +} + +#define GFD_BUFSIZE 19432 +static char *digita_file_get(int index, int thumbnail, int *size) +{ + struct filename fn; + struct partial_tag tag; + unsigned char *data; + int i, ret, pos, len, buflen; + + printf("digita: camera_file_get\n"); + + if (index > digita_num_pictures) { + fprintf(stderr, "digita: index %d out of range\n", index); + return NULL; + } + + printf("digita: getting %d, %s%s\n", index, digita_file_list[index].fn.path, digita_file_list[index].fn.dosname); + + /* Setup the filename */ + fn.driveno = digita_file_list[index].fn.driveno; + strcpy(fn.path, digita_file_list[index].fn.path); + strcpy(fn.dosname, digita_file_list[index].fn.dosname); + + /* How much data we're willing to accept */ + tag.offset = htonl(0); + tag.length = htonl(GFD_BUFSIZE); + tag.filesize = htonl(0); + + buflen = GFD_BUFSIZE; + data = malloc(buflen); + if (!data) { + fprintf(stderr, "allocating memory\n"); + return NULL; + } + memset(data, 0, buflen); + + gp_progress(0.00); + + if (digita_get_file_data(dev, thumbnail, &fn, &tag, data) < 0) { + printf("digita_get_picture: digita_get_file_data failed\n"); + return NULL; + } + + buflen = ntohl(tag.filesize); + if (thumbnail) + buflen += 16; + + data = realloc(data, buflen); + if (!data) { + fprintf(stderr, "couldn't reallocate memory\n"); + return NULL; + } + + len = ntohl(tag.filesize); + pos = ntohl(tag.length); + while (pos < len) { + gp_progress((float)pos / (float)len); + tag.offset = htonl(pos); + if ((len - pos) > GFD_BUFSIZE) + tag.length = htonl(GFD_BUFSIZE); + else + tag.length = htonl(len - pos); + + if (digita_get_file_data(dev, thumbnail, &fn, &tag, data + pos) < 0) { + printf("digita_get_picture: digita_get_file_data failed\n"); + return NULL; + } + pos += ntohl(tag.length); + } + + gp_progress(1.00); + + return data; +} + +int camera_file_get(int index, CameraFile *file) +{ + unsigned char *data; + int buflen; + + data = digita_file_get(index, 0, &buflen); + if (!data) + return GP_ERROR; + + file->data = data; + strcpy(file->type, "image/jpeg"); + file->size = buflen; + + snprintf(file->name, sizeof(file->name), "%s%s", + digita_file_list[index].fn.path, + digita_file_list[index].fn.dosname); + + return GP_OK; +} + +char *ppmheadfmt = "P6\n# test.ppm\n%i %i\n255\n"; + +int camera_file_get_preview(int index, CameraFile *file) +{ + unsigned char *data; + int i, buflen; + unsigned char *buf, *rgb, *ps; + unsigned int *ints, width, height; + char ppmhead[64]; + + data = digita_file_get(index, 0, &buflen); + if (!data) + return GP_ERROR; + + ints = (unsigned int *)data; + width = ntohl(ints[2]); + height = ntohl(ints[1]); + + sprintf(ppmhead, ppmheadfmt, height - 1, width - 1); + + buf = malloc((width * height * 3) + strlen(ppmhead)); + if (!buf) { + fprintf(stderr, "error allocating rgb data\n"); + return GP_ERROR; + } + + strcpy(buf, ppmhead); + + rgb = buf + strlen(buf); + + ps = data + 16; + for (i = 0; i < height; i++) { + char *pd = rgb + (width * ((height - 1) - i) * 3); + while (ps < data + 16 + (width * i * 2)) { + int y, u, y1, v, r, g, b; + +#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16) + +u = *ps++ - 128; +y = *ps++ - 16; +v = *ps++ - 128; +y1 = *ps++ - 16; +r = 104635 * v; +g = -25690 * u + -53294 * v; +b = 132278 * u; +y *= 76310; +y1 *= 76310; +*pd++ = LIMIT(b + y); *pd++ = LIMIT(g + y); *pd++ = LIMIT(r + y); +*pd++ = LIMIT(b + y1); *pd++ = LIMIT(g + y1); *pd++ = LIMIT(r + y1); + } + } + + free(data); + + file->data = buf; + strcpy(file->type, "image/ppm"); + file->size = (width * height * 3) + sizeof(ppmhead); + + snprintf(file->name, sizeof(file->name), "%s%s", + digita_file_list[index].fn.path, + digita_file_list[index].fn.dosname); + + return GP_OK; +} + +int camera_file_put(CameraFile *file) +{ + return GP_OK; +} + +int camera_file_delete(int file_number) +{ + return GP_OK; +} + +int camera_config_get(CameraWidget *window) +{ + return GP_ERROR; +} + +int camera_config_set(CameraSetting *setting, int count) +{ + return GP_ERROR; +} + +int camera_capture(CameraFile *file, CameraCaptureInfo *info) +{ + return GP_ERROR; +} + +int camera_summary(CameraText *summary) +{ + int taken; + + if (digita_get_storage_status(dev, &taken, NULL, NULL) < 0) + return 0; + + sprintf(summary->text, "Number of pictures: %d", taken); + + return GP_OK; +} + +int camera_manual(CameraText *manual) +{ + strcpy(manual->text, "Manual Not Available"); + + return GP_OK; +} + +int camera_about(CameraText *about) +{ + strcpy(about->text, "Digita\n" \ + "Johannes Erdfelt \n" \ + "VA Linux Systems, Inc"); + + return GP_OK; +} + +static int delete_picture(int index) +{ + struct filename fn; + int ret; + + printf("digita_delete_picture\n"); + + if (index > digita_num_pictures) + return 0; + + index--; + + printf("deleting %d, %s%s\n", index, digita_file_list[index].fn.path, digita_file_list[index].fn.dosname); + + /* Setup the filename */ + fn.driveno = digita_file_list[index].fn.driveno; + strcpy(fn.path, digita_file_list[index].fn.path); + strcpy(fn.dosname, digita_file_list[index].fn.dosname); + + if (digita_delete_picture(dev, &fn) < 0) + return 0; + + if (digita_get_file_list(dev) < 0) + return 0; + + return 1; +} + diff --git a/camlibs/digita/digita.h b/camlibs/digita/digita.h new file mode 100644 index 000000000..d1fa5971e --- /dev/null +++ b/camlibs/digita/digita.h @@ -0,0 +1,140 @@ +#ifndef DIGITA_H +#define DIGITA_H + +#include + +struct digita_device { + gpio_device *gpdev; + + /* These parameters are only significant for serial support */ + int portspeed; + + int deviceframesize; +}; + +#define DIGITA_GET_PRODUCT_INFO 0x01 +#define DIGITA_GET_IMAGE_SPECS 0x02 +#define DIGITA_GET_CAMERA_STATUS 0x03 +#define DIGITA_SET_PRODUCT_INFO 0x05 +#define DIGITA_GET_CAMERA_CAPABILITIES 0x10 +#define DIGITA_GET_CAMERA_STATE 0x11 +#define DIGITA_SET_CAMERA_STATE 0x12 +#define DIGITA_GET_CAMERA_DEFAULTS 0x13 +#define DIGITA_SET_CAMERA_DEFAULTS 0x14 +#define DIGITA_RESTORE_CAMERA_STATES 0x15 +#define DIGITA_GET_SCENE_ANALYSIS 0x18 +#define DIGITA_GET_POWER_MODE 0x19 +#define DIGITA_SET_POWER_MODE 0x1A +#define DIGITA_GET_S1_MODE 0x1D +#define DIGITA_SET_S1_MODE 0x1E +#define DIGITA_START_CAPTURE 0x1F +#define DIGITA_GET_FILE_LIST 0x40 +#define DIGITA_GET_NEW_FILE_LIST 0x41 +#define DIGITA_GET_FILE_DATA 0x42 +#define DIGITA_ERASE_FILE 0x43 +#define DIGITA_GET_STORAGE_STATUS 0x44 +#define DIGITA_SET_FILE_DATA 0x47 +#define DIGITA_GET_FILE_TAG 0x48 +#define DIGITA_SET_USER_FILE_TAG 0x49 +#define DIGITA_GET_CLOCK 0x70 +#define DIGITA_SET_CLOCK 0x71 +#define DIGITA_GET_ERROR 0x78 +#define DIGITA_GET_INTERFACE_TIMEOUT 0x90 +#define DIGITA_SET_INTERFACE_TIMEOUT 0x91 + +/* Digita protocol primitives */ +struct digita_command { + unsigned int length; + unsigned int unknown; + unsigned short command; + unsigned short status; +}; + +struct partial_tag { + unsigned int offset; + unsigned int length; + unsigned int filesize; +}; + +struct filename { + unsigned int driveno; + unsigned char path[32]; + unsigned char dosname[16]; +}; + +struct file_item { + struct filename fn; + + int length; + unsigned int filestatus; +}; + +/* Digita protocol commands */ + +/* DIGITA_GET_FILE_DATA */ +/* + * sent - digita_command + * get_file_data_send + */ +/* + * received - get_file_data_receive + * data + */ +struct get_file_data_send { + struct digita_command cmd; + + struct filename fn; + + unsigned int dataselector; + + struct partial_tag tag; +}; + +struct get_file_data_receive { + struct digita_command cmd; + + struct partial_tag tag; +}; + +/* DIGITA_GET_FILE_LIST */ +/* sent - get_file_list */ +/* + * received - digita_command + * data + */ +struct get_file_list { + struct digita_command cmd; + + unsigned int listorder; +}; + +/* DIGITA_ERASE_FILE */ +/* sent - erase_file */ +/* received - nothing */ +struct erase_file { + struct digita_command cmd; + + struct filename fn; +}; + +extern int (*digita_send)(struct digita_device *dev, void *buffer, int buflen); +extern int (*digita_read)(struct digita_device *dev, void *buffer, int buflen); +extern int digita_num_pictures; +extern struct file_item *digita_file_list; + +/* commands.c */ +int digita_get_storage_status(struct digita_device *dev, int *taken, + int *available, int *rawcount); +int digita_get_file_list(struct digita_device *dev); +int digita_get_file_data(struct digita_device *dev, int thumbnail, + struct filename *filename, struct partial_tag *tag, void *buffer); +int digita_delete_picture(struct digita_device *dev, struct filename *filename); + +/* serial.c */ +struct digita_device *digita_serial_open(void); + +/* usb.c */ +struct digita_device *digita_usb_open(void); + +#endif + diff --git a/camlibs/digita/serial.c b/camlibs/digita/serial.c new file mode 100644 index 000000000..36fb0d19b --- /dev/null +++ b/camlibs/digita/serial.c @@ -0,0 +1,259 @@ +/* + * serial.c + * + * Serial digita support + * + * Copyright 1999-2000 Johannes Erdfelt + */ + +#include +#include +#include +#include + +#include "digita.h" + +#include + +struct beacon { + unsigned short intro; + unsigned short vendorid; + unsigned short deviceid; + unsigned char checksum; +} __attribute__ ((packed)); + +struct beacon_ack { + unsigned short intro; + unsigned char intftype; + unsigned int cf_reserved:4; + unsigned int cf_pod_receive_mode:2; + unsigned int cf_host_receive_mode:2; + unsigned int dataspeed; + unsigned short deviceframesize; + unsigned short hostframesize; + unsigned char checksum; +} __attribute__ ((packed)); + +struct beacon_comp { + unsigned char result; + unsigned int cf_reserved:4; + unsigned int cf_pod_receive_mode:2; + unsigned int cf_host_receive_mode:2; + unsigned int dataspeed; + unsigned short deviceframesize; + unsigned short hostframesize; +} __attribute__ ((packed)); + +#define POLL_LENGTH_MASK 0x03FF +#define POLL_BOB 0x0400 +#define POLL_EOB 0x0800 +#define POLL_CMD 0x1000 +#define POLL_POLL_MASK 0xE000 +#define POLL_POLL_SHIFT 13 + +#define POLL_ACK 0x01 +#define POLL_NAK 0x02 + +static unsigned int checksum(const unsigned char *buffer, int len) +{ + int i; + int limit = len - 1; + unsigned int sum = 0; + + for (i = 0; i < limit; i++) + sum += *(buffer++); + + return sum & 0xff; +} + +static int poll_and_wait(gpio_device *dev, int length, int bob, int eob) +{ + unsigned short s, poll, poll_reply; + + do { + poll = (1 << POLL_POLL_SHIFT) | POLL_CMD | length | + (bob ? POLL_BOB : 0) | (eob ? POLL_EOB : 0); + + s = htons(poll); + if (gpio_write(dev, (void *)&s, sizeof(s)) < 0) + return -1; + if (gpio_read(dev, (void *)&s, sizeof(s)) < 0) + return -1; + poll_reply = ntohs(s); +if (poll_reply & POLL_ACK) +printf("POLL_ACK\n"); +if (poll_reply & POLL_NAK) +printf("POLL_NAK\n"); + } while (poll_reply & POLL_NAK); + + return 0; +} + +static int digita_serial_send(struct digita_device *dev, void *_buffer, int len) +{ + unsigned char *buffer = _buffer; + unsigned short s; + int sent = 0, size; + + while (sent < len) { + if ((len - sent) > dev->deviceframesize) + size = dev->deviceframesize; + else + size = len - sent; + + poll_and_wait(dev->gpdev, size, sent == 0, (size + sent) == len); + + if (gpio_write(dev->gpdev, buffer + sent, size) < 0) + return -1; + + sent += size; + } + + s = 0; + if (gpio_write(dev->gpdev, (void *)&s, sizeof(s)) < 0) + return -1; + + return len; +} + +static int poll_and_reply(gpio_device *dev, int *length, int *eob, int nak) +{ + unsigned short s, poll, poll_reply; + + if (gpio_read(dev, (void *)&s, sizeof(s)) < 0) + return -1; + + poll = ntohs(s); + if (length) + *length = poll & POLL_LENGTH_MASK; + if (eob) + *eob = poll & POLL_EOB; + + if (nak) + poll_reply = POLL_NAK; + else + poll_reply = POLL_ACK; + + s = htons(poll_reply); + if (gpio_write(dev, (void *)&s, sizeof(s)) < 0) + return -1; + + return 0; +} + +static int digita_serial_read(struct digita_device *dev, void *_buffer, int len) +{ + unsigned char *buffer = _buffer; + unsigned short s; + int received = 0, size, eob; + + while (received < len) { + poll_and_reply(dev->gpdev, &size, &eob, 0); + + if (gpio_read(dev->gpdev, buffer + received, size) < 0) + return -1; + + received += size; + if (eob) + break; + } + + if (gpio_read(dev->gpdev, (void *)&s, sizeof(s)) < 0) + return -1; + + return received; +} + +struct digita_device *digita_serial_open(void) +{ + struct digita_device *dev; + gpio_device_settings settings; + struct beacon beacon; + struct beacon_ack beacon_ack; + struct beacon_comp beacon_comp; + + dev = malloc(sizeof(*dev)); + if (!dev) + return NULL; + + dev->gpdev = gpio_new(GPIO_DEVICE_SERIAL); + if (!dev->gpdev) + return NULL; + +/* + strcpy(settings.serial.port, serial_port); +*/ + strcpy(settings.serial.port, "/dev/ttyS0"); + settings.serial.speed = 9600; + settings.serial.bits = 8; + settings.serial.parity = 0; + settings.serial.stopbits = 1; + + digita_send = digita_serial_send; + digita_read = digita_serial_read; + + gpio_set_settings(dev->gpdev, settings); + if (gpio_open(dev->gpdev) < 0) { + fprintf(stderr, "error opening device\n"); + return NULL; + } + + tcsendbreak(dev->gpdev->device_fd, 4); + + dev->gpdev->settings.serial.speed = 0; + gpio_serial_set_baudrate(dev->gpdev); + + usleep(50); + + dev->gpdev->settings.serial.speed = 9600; + gpio_serial_set_baudrate(dev->gpdev); + + usleep(2000); + + memset((void *)&beacon, 0, sizeof(beacon)); + if (gpio_read(dev->gpdev, (void *)&beacon, sizeof(beacon)) < 0) { + perror("reading beacon"); + return NULL; + } + + printf("%04X %04X %04X %02X\n", + beacon.intro, beacon.vendorid, + beacon.deviceid, beacon.checksum); + +// #define SPEED 57600 +#define SPEED 115200 + beacon_ack.intro = htons(0x5aa5); + beacon_ack.intftype = 0x55; + beacon_ack.cf_reserved = 0; + beacon_ack.cf_pod_receive_mode = 0; + beacon_ack.cf_host_receive_mode = 0; + beacon_ack.dataspeed = htonl(SPEED); + beacon_ack.deviceframesize = htons(1023); + beacon_ack.hostframesize = htons(1023); + beacon_ack.checksum = 0; + beacon_ack.checksum = checksum((void *)&beacon_ack, sizeof(beacon_ack)); + + if (gpio_write(dev->gpdev, (void *)&beacon_ack, sizeof(beacon_ack)) < +0) { + perror("writing beacon_ack"); + return NULL; + } + + if (gpio_read(dev->gpdev, (void *)&beacon_comp, sizeof(beacon_comp)) < 0) { + perror("reading beacon_comp"); + return NULL; + } + +printf("%d\n", ntohl(beacon_comp.dataspeed)); + usleep(100000); + + dev->deviceframesize = ntohs(beacon_comp.deviceframesize); + + dev->gpdev->settings.serial.speed = ntohl(beacon_comp.dataspeed); + gpio_serial_set_baudrate(dev->gpdev); + + usleep(100000); + + return dev; +} + diff --git a/camlibs/digita/usb.c b/camlibs/digita/usb.c new file mode 100644 index 000000000..e9a83c25b --- /dev/null +++ b/camlibs/digita/usb.c @@ -0,0 +1,90 @@ +/* + * usb.c + * + * USB digita support + * + * Copyright 1999-2000, Johannes Erdfelt + */ + +#include +#include +#include + +#include "digita.h" + +#include + +static int digita_usb_read(struct digita_device *dev, void *buffer, int len) +{ +#ifdef GPIO_USB + return gpio_read(dev->gpdev, buffer, len); +#else + return GPIO_ERROR; +#endif +} + +static int digita_usb_send(struct digita_device *dev, void *buffer, int len) +{ +#ifdef GPIO_USB + return gpio_write(dev->gpdev, buffer, len); +#else + return GPIO_ERROR; +#endif +} + +#ifdef GPIO_USB +int digita_usb_probe(struct usb_device **udev) +{ + if (gpio_usb_find_device(0x040A, 0x0110, udev)) { + printf("found '%s' @ %s/%s\n", "Kodak DC260", + (*udev)->bus->dirname, (*udev)->filename); + return 1; + } + + fprintf(stderr, "unable to find any compatible USB cameras\n"); + + return 0; +} +#endif + +struct digita_device *digita_usb_open(void) +{ +#ifdef GPIO_USB + struct digita_device *dev; + gpio_device_settings settings; + struct usb_device *udev; + + if (!digita_usb_probe(&udev)) + return NULL; + + dev = malloc(sizeof(*dev)); + if (!dev) + return NULL; + + dev->gpdev = gpio_new(GPIO_DEVICE_USB); + if (!dev->gpdev) + return NULL; + + settings.usb.udev = udev; + + settings.usb.inep = 0x81; + settings.usb.outep = 0x02; + settings.usb.config = 1; + settings.usb.interface = 0; + settings.usb.altsetting = 0; + + digita_send = digita_usb_send; + digita_read = digita_usb_read; + + gpio_set_settings(dev->gpdev, settings); + if (gpio_open(dev->gpdev) < 0) { + fprintf(stderr, "error opening device\n"); + return NULL; + } + + return dev; +#else + return NULL; +#endif +} +