static char rcsid[] = "$Id: samsung.c,v 1.2 2000/02/17 15:35:18 root Exp root $"; #include #include #include #include #include #include #include #include #include #include #define TIMEOUT 500000 #define serial_port "/dev/ttyS0" #undef DEBUG typedef unsigned char byte; int fd; void error_dialog (char *err) { fprintf (stderr, err); fprintf (stderr, "\n"); } #define OHSHIT do { fprintf(stderr,"OHSHIT: " __FILE__ " line %d\n",__LINE__); exit(0); } while (0) static int sendcommand (byte * cmd, int len) { #ifdef DEBUG int i; fprintf (stderr, "Send:"); for (i = 0; i < len; ++i) { fprintf (stderr, " %02x", cmd[i]); } fprintf (stderr, "\n"); #endif return write (fd, cmd, len); } static int waitforinput () { fd_set rfds; struct timeval tv; tv.tv_sec = 5; tv.tv_usec = TIMEOUT; FD_ZERO (&rfds); FD_SET (fd, &rfds); if (!select (fd + 1, &rfds, NULL, NULL, &tv)) return 0; if (!FD_ISSET (fd, &rfds)) return 0; return 1; } static int receive (byte * buf, int expected) { int tries = 0; int n, total, i; byte *ptr; { ptr = buf; i = expected; total = 0; while (waitforinput (fd)) { n = read (fd, ptr, i); if (n > 0) { ptr += n; i -= n; total += n; if (total == expected) { #ifdef DEBUG fprintf (stderr, "Read %d bytes as expected\n", total); #endif return total; } } } #ifdef DEBUG fprintf (stderr, "Read %d byes of %d bytes expected\n", total, expected); #endif return total; } } static byte getbyte (void) { byte b; if (receive (&b, 1) != 1) { #ifdef DEBUG fprintf (stderr, "Getbyte: FAILED\n", b); #endif return 0; } #ifdef DEBUG fprintf (stderr, "Getbyte: %02x\n", b); #endif return b; } static int sendcommand1 (byte b) { if (sendcommand (&b, 1) != 1) return 0; if (getbyte () != b) return 0; return 1; } static int sendcommand2 (byte b1, byte b2) { byte b[2] = { b1, b2 }; if (sendcommand (b, 2) != 2) return 0; if (getbyte () != b1) return 0; return 1; } static int sendcommand3 (byte b1, byte b2, byte b3) { byte b[3] = { b1, b2, b3 }; if (sendcommand (b, 3) != 3) return 0; if (getbyte () != b1) return 0; return 1; } static int sendcommand5 (byte b1, byte b2, byte b3, byte b4, byte b5) { byte b[6] = { b1, b2, b3, b4, b5 }; if (sendcommand (b, 5) != 5) return 0; if (getbyte () != b1) return 0; return 1; } static int init_comms () { struct termios tios; unsigned char buf[0x100]; tcgetattr (fd, &tios); tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL | CRTSCTS); tios.c_cflag |= CLOCAL; tios.c_cflag |= CS8; tios.c_cflag |= CREAD | HUPCL; tios.c_iflag = IGNBRK | IGNPAR; tios.c_oflag = 0; tios.c_lflag = 0; tios.c_cc[VMIN] = 1; tios.c_cc[VTIME] = 0; cfsetospeed (&tios, B9600); cfsetispeed (&tios, B9600); if (tcsetattr (fd, TCSAFLUSH, &tios) < 0) error_dialog ("Error setting communication parameters"); tcsendbreak (fd, 0); sleep (1); //Do ping if (!sendcommand1 (0x1)) { OHSHIT; return 0; } //Switch baud rate if (!sendcommand2 (0x69, 0x0b)) { OHSHIT; return 0; } cfsetospeed (&tios, B115200); cfsetispeed (&tios, B115200); if (tcsetattr (fd, TCSAFLUSH, &tios) < 0) error_dialog ("Error setting communication parameters"); return 1; } static int SDSC_Initialise (void) { fd = open (serial_port, O_RDWR); if (fd < 0) { error_dialog ("Couldn't open camera device"); return 1; } if (!init_comms (fd)) { error_dialog ("Couldn't init comm port"); return 1; } return 0; } static int checksum (byte * buf) { int i = 0; int k = 256; while (k--) { i += (int) *(buf++); i = i & 0xff; } if (i != *buf) { fprintf (stderr, "CHECKSUM %02x:%02x\n", i, *buf); return 0; } return 1; } static int fetchpacket (int pn, byte * buf) { do { if (!sendcommand5 (0x15, (pn >> 8) & 0xff, pn & 0xff, 0x0, 0x1)) { OHSHIT; return 0; } } while (receive (buf, 257) != 257); return checksum (buf); } dumppacket (byte * octopus) { int j, k; for (j = 0; j < 0x100; j += 0x10) { printf ("%04x:", j); for (k = 0; k < 0x10; k++) { printf (" %02x", octopus[j + k]); } printf ("\n"); } } int pictures () { byte octopus1[257]; byte octopus2[257]; if (!sendcommand2 (0x61, 0x40)) OHSHIT; memset (octopus1, 0, sizeof (octopus1)); if (!fetchpacket (0, octopus1)) OHSHIT; if (!sendcommand2 (0x61, 0x40)) OHSHIT; memset (octopus2, 0xff, sizeof (octopus2)); if (!fetchpacket (0, octopus2)) OHSHIT; if (memcmp (octopus1, octopus2, sizeof (octopus1))) OHSHIT; return octopus1[10]; } bar () { byte octopus[257]; int i, j, k; sendcommand2 (0x61, 0x80); for (i = 0; i < 4; ++i) { if (!fetchpacket (i, octopus)) { OHSHIT; return; } //dumppacket(octopus); } } qux (int i) { byte buf[8]; { sendcommand2 (0xf6, i); if (receive (buf, 8) != 8) { OHSHIT; return; } /*printf("F6: %d: %02x %02x %02x %02x %02x %02x %02x %02x\n", i, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); */ } } thumb (FILE * f) { byte octopus[257]; int i; sendcommand2 (0x61, 0x2); for (i = 0; i < 0x30; ++i) { if (!fetchpacket (i, octopus)) { OHSHIT; return; } fwrite (octopus, 1, 256, f); } } full (FILE * f) { byte octopus[257]; int i, j; sendcommand2 (0x61, 0x1); for (i = 0; i < 0x800; ++i) { j = printf ("Fetching full image %d/%d", i, 0x800); while (j--) putchar (8); fflush (stdout); if (!fetchpacket (i, octopus)) { OHSHIT; return; } fwrite (octopus, 1, 256, f); } } int main (int argc, char *argv[]) { FILE *f; char name[1024]; int i; int n; SDSC_Initialise (); n = pictures (); printf ("Camera has %d pictures\n", n); for (i = 1; i <= n; ++i) { printf ("Getting thumb %d...", i); fflush (stdout); bar (); qux (i); sprintf (name, "thumb%04d.thm", i); f = fopen (name, "w"); thumb (f); fclose (f); printf ("Done\n"); } while (--argc) { bar (); i = atoi (*(++argv)); qux (i); printf ("Fetching fullimage %d\n", i); sprintf (name, "full%04d.cmp", i); f = popen (name, "w"); full (f); fclose (f); } return 0; }