/* * waits for the Commit value * The function expexts the commandid auf the corresponding command * to determiante, wether a long timeout is needed or not. (Take Photo) */ int mdc800_rs232_waitForCommit (char commandid) { char ch[1]; if (mdc800_io_device_handle == 0) { printCError ("(mdc800_rs232_waitForCommit) Camera is not open !\n"); return 0; } gpio_set_timeout (mdc800_io_device_handle, mdc800_io_getCommandTimeout (commandid) ); if (gpio_read (mdc800_io_device_handle,ch,1) != GPIO_OK) { printCError ("(mdc800_rs232_waitForCommit) Error receiving commit !\n"); return 0; } if (ch[0] != ANSWER_COMMIT ) { printCError ("(mdc800_rs232_waitForCommit) Byte \"%i\" was not the commit !\n",ch[0]); return 0; } return (1); }
/* * downloads data from camera and send * a checksum every 512 bytes. */ int mdc800_rs232_download (char* buffer, int size) { int checksum,readen=0,i; char DSC_checksum; int numtries=0; gpio_set_timeout (mdc800_io_device_handle, MDC800_DEFAULT_TIMEOUT ); while (readen < size) { if (size) update_progress (100 * readen / size); if (!mdc800_rs232_receive (&buffer[readen],512)) return readen; checksum=0; for (i=0; i<512; i++) checksum=(checksum+(unsigned char) buffer [readen+i])%256; if (gpio_write (mdc800_io_device_handle,(char*) &checksum,1) != GPIO_OK) return readen; if (!mdc800_rs232_receive (&DSC_checksum,1)) return readen; if ((char) checksum != DSC_checksum) { numtries++; printCError ("(mdc800_rs232_download) checksum: software %i, DSC %i , reload block! (%i) \n",checksum,(unsigned char)DSC_checksum,numtries); if (numtries > 10) { printCError ("(mdc800_rs232_download) to many retries, giving up.."); return 0; } } else { readen+=512; numtries=0; } } { int i,j; unsigned char* b=(unsigned char*) buffer; for (i=0; i<4; i++) { printCError ("%i: ",i); for (j=0; j<8; j++) printCError (" %i", b[i*8+j]); printCError ("\n"); } } if (size) update_progress (100 * readen/size); return readen; }
/* * Waits for the camera * type: 0: Wait until the camera gets ready * 1: Read data from irq * The function stores the readen 8 Bytes in data. * and return 0 on success else -1. */ static int mdc800_usb_readFromIrq (GPPort *port,int type,unsigned char* data,int timeout) { int ret; struct timeval tv; gp_port_set_timeout(port,1); timeout+=10*MDC800_USB_IRQ_INTERVAL; gettimeofday(&tv,NULL); while (timeout>=0) { /* try a read */ ret = gp_port_check_int(port,(char*)data,8); if (ret!=8) { printCError ("(mdc800_usb_readFromIRQ) reading bytes from irq fails (%d)\n",ret); return ret; } if (0) { int i=0; printf ("irq :"); for (i=0; i<8; i++) { printf ("%i ", data [i]); } printf ("\n"); } /* check data */ if (type) { if (!(mdc800_usb_isReady(data)||mdc800_usb_isBusy(data))) { fprintf(stderr,"got data.\n"); /* Data received successfull */ return GP_OK; } } else { if (mdc800_usb_isReady (data)) { fprintf(stderr,"got readiness.\n"); /* Camera response ready */ return GP_OK; } } /* wait the specified time */ if (1) { usleep(MDC800_USB_IRQ_INTERVAL * 1000); timeout-=MDC800_USB_IRQ_INTERVAL; } } /* Timeout */ printCError ("(mdc800_usb_readFromIrq) timeout\n"); return GP_ERROR_IO; }
/* * downloads data from camera and send * a checksum every 512 bytes. */ int mdc800_rs232_download (GPPort *port,unsigned char* buffer, int size) { int readen=0,i,j; unsigned char checksum; unsigned char DSC_checksum; int numtries=0; gp_port_set_timeout(port, MDC800_DEFAULT_TIMEOUT ); while (readen < size) { if (!mdc800_rs232_receive (port,&buffer[readen],512)) return readen; checksum=0; for (i=0; i<512; i++) checksum=(checksum+buffer[readen+i])%256; if (gp_port_write (port,(char*) &checksum,1) < GP_OK) return readen; if (!mdc800_rs232_receive (port,&DSC_checksum,1)) return readen; if (checksum != DSC_checksum) { numtries++; printCError ("(mdc800_rs232_download) checksum: software %i, DSC %i , reload block! (%i) \n",checksum,DSC_checksum,numtries); if (numtries > 10) { printCError ("(mdc800_rs232_download) to many retries, giving up.."); return 0; } } else { readen+=512; numtries=0; } } for (i=0; i<4; i++) { printCError ("%i: ",i); for (j=0; j<8; j++) printCError (" %i", buffer[i*8+j]); printCError ("\n"); } return readen; }
/* * receive Bytes from camera */ int mdc800_rs232_receive (char* buffer, int b) { if (mdc800_io_device_handle == 0) { printCError ("(mdc800_rs232_receive) Camera is not open !\n"); return 0; } gpio_set_timeout (mdc800_io_device_handle, MDC800_DEFAULT_TIMEOUT ); if (gpio_read (mdc800_io_device_handle, buffer,b) != GPIO_OK) { printCError ("(mdc800_rs232_receive) can't read %i Bytes !\n",b); return 0; } return 1; }
/* * waits for the Commit value * The function expects the commandid of the corresponding command * to determine whether a long timeout is needed or not. (Take Photo) */ int mdc800_rs232_waitForCommit (GPPort *port,char commandid) { unsigned char ch[1]; int ret; gp_port_set_timeout(port,mdc800_io_getCommandTimeout(commandid)); ret = gp_port_read(port,ch,1); if (ret!=1) { printCError ("(mdc800_rs232_waitForCommit) Error receiving commit !\n"); return GP_ERROR_IO; } if (ch[0] != ANSWER_COMMIT ) { printCError ("(mdc800_rs232_waitForCommit) Byte \"%i\" was not the commit !\n",ch[0]); return GP_ERROR_IO; } return GP_OK; }
/* * receive Bytes from camera */ int mdc800_rs232_receive (GPPort *port,unsigned char* buffer, int b) { int ret; gp_port_set_timeout (port,MDC800_DEFAULT_TIMEOUT ); ret=gp_port_read(port,(char*)buffer,b); if (ret!=b) { printCError ("(mdc800_rs232_receive) can't read %i Bytes !\n",b); return GP_ERROR_IO; } return GP_OK; }
/* * sends a command and receives the answer to this * buffer: Strores the answer * length: length of answer or null */ int mdc800_rs232_sendCommand (char* command, char* buffer, int length) { char answer; int fault=0; struct timeval timeout; int i; if (mdc800_io_device_handle == 0) { printCError ("(mdc800_rs232_sendCommand) Camera is not open !\n"); return 0; } printFnkCall ("(mdc800_rs232_sendCommand) id:%i (%i,%i,%i),answer:%i\n",command[1],command[2],command[3],command[4],length); timeout.tv_usec = MDC800_DEFAULT_COMMAND_DELAY*1000; timeout.tv_sec = 0; select (1 , NULL, NULL, NULL, &timeout); gpio_set_timeout (mdc800_io_device_handle, MDC800_DEFAULT_TIMEOUT ); // Send command for (i=0; i<6; i++) { if (gpio_write (mdc800_io_device_handle, &command[i] ,1) != GPIO_OK) { printCError ("(mdc800_rs232_sendCommand) sending Byte %i fails!\n",i); fault=1; } if (gpio_read (mdc800_io_device_handle,&answer,1) != GPIO_OK) { printCError ("(mdc800_rs232_sendCommand) receiving resend of Byte %i fails.\n",i); fault=1; } if (command [i] != answer) { printCError ("(mdc800_rs232_sendCommand) Byte %i differs : send %i, received %i \n",i,command[i],answer); fault=1; } } if (fault) return 0; // Receive answer if (length) { // Some Commands needs a download. switch (command[1]) { case COMMAND_GET_IMAGE: case COMMAND_GET_THUMBNAIL: if (!mdc800_rs232_download (buffer,length)) { printCError ("(mdc800_rs232_sendCommand) download of %i Bytes fails.\n",length); fault=1; } break; default: if (!mdc800_rs232_receive (buffer,length)) { printCError ("(mdc800_rs232_sendCommand) receiving %i Bytes fails.\n",length); fault=1; } } } if (fault) return 0; // commit if (!(command[1] == COMMAND_CHANGE_RS232_BAUD_RATE)) if (!mdc800_rs232_waitForCommit (command[1])) { printCError ("(mdc800_rs232_sendCommand) receiving commit fails.\n"); fault=1; } if (fault) return 0; // all right return 1; }
int mdc800_usb_sendCommand(GPPort*port,unsigned char*command,unsigned char*buffer,int length) { unsigned char tmp_buffer [16]; GPPortSettings settings; int ret; printf ("(mdc800_usb_sendCommand) id:%i (%i,%i,%i,%i,%i,%i),answer:%i\n",command[1],command[2],command[3],command[4],command[5],command[6],command[7],length); /* Send the Command */ gp_port_set_timeout(port,MDC800_DEFAULT_TIMEOUT); gp_port_get_settings(port,&settings); settings.usb.outep = MDC800_USB_ENDPOINT_COMMAND; gp_port_set_settings(port,settings); ret = mdc800_usb_readFromIrq(port,0,tmp_buffer,MDC800_DEFAULT_TIMEOUT); if (ret != GP_OK) { fprintf(stderr,"Camera did not get ready before mdc800_usb_sendCommand!\n"); } if ((ret=gp_port_write(port,(char*)command,8)) != 8) { printCError ("(mdc800_usb_sendCommand) sending Command fails (%d)!\n",ret); return ret; } /* receive the answer */ switch (command [1]) { case COMMAND_GET_THUMBNAIL: case COMMAND_GET_IMAGE: gp_port_set_timeout (port, 2000); if (gp_port_read (port,(char*)buffer,64) != 64) { printCError ("(mdc800_usb_sendCommand) requesting 64Byte dummy data fails.\n"); return GP_ERROR_IO; } fprintf(stderr,"got 64 byte\n"); { /* Download loop */ int readen=0; while (readen < length) { if (gp_port_read(port,(char*)(buffer+readen),64) != 64) { printCError ("(mdc800_usb_sendCommand) reading image data fails.\n"); return 0; } fprintf(stderr,"got 64 byte\n"); readen+=64; } } break; default : if (length > 0) { ret = mdc800_usb_readFromIrq (port,1,tmp_buffer, mdc800_io_getCommandTimeout(command[1])); if (ret != GP_OK) { /* Reading fails */ printCError ("(mdc800_usb_sendCommand) receiving answer fails (%d).\n",ret); return ret; } memcpy(buffer,tmp_buffer,length); } } #if 1 /* Waiting for camera to get ready */ ret = mdc800_usb_readFromIrq(port,0,tmp_buffer,mdc800_io_getCommandTimeout (command[1])); if (ret!=GP_OK) { /* Reading fails */ printCError ("(mdc800_usb_sendCommand) camera didn't get ready in the defined intervall ?!\n"); return ret; } #endif return GP_OK; }
/* * sends a command and receives the answer to this * buffer: Strores the answer * length: length of answer or null */ int mdc800_rs232_sendCommand(GPPort *port,unsigned char* command, unsigned char* buffer, int length) { char answer; int fault=0,ret; int i; printFnkCall ("(mdc800_rs232_sendCommand) id:%i (%i,%i,%i),answer:%i\n",command[1],command[2],command[3],command[4],length); usleep(MDC800_DEFAULT_COMMAND_DELAY*1000); gp_port_set_timeout (port, MDC800_DEFAULT_TIMEOUT ); /* Send command */ for (i=0; i<6; i++) { if (gp_port_write (port, (char*)&command[i] ,1) < GP_OK) { printCError ("(mdc800_rs232_sendCommand) sending Byte %i fails!\n",i); fault=1; } ret = gp_port_read (port,&answer,1); if ( ret != 1) { printCError ("(mdc800_rs232_sendCommand) receiving resend of Byte %i fails.\n",i); fault=1; } if (command [i] != answer) { printCError ("(mdc800_rs232_sendCommand) Byte %i differs : send %i, received %i \n",i,command[i],answer); fault=1; } } if (fault) return GP_ERROR_IO; /* Receive answer */ if (length) { /* Some Commands needs a download. */ switch (command[1]) { case COMMAND_GET_IMAGE: case COMMAND_GET_THUMBNAIL: if (!mdc800_rs232_download(port,buffer,length)) { printCError ("(mdc800_rs232_sendCommand) download of %i Bytes fails.\n",length); fault=1; } break; default: if (!mdc800_rs232_receive(port,buffer,length)) { printCError ("(mdc800_rs232_sendCommand) receiving %i Bytes fails.\n",length); fault=1; } } } if (fault) return GP_ERROR_IO; /* commit */ if (!(command[1] == COMMAND_CHANGE_RS232_BAUD_RATE)) { if (!mdc800_rs232_waitForCommit(port,command[1])) { printCError ("(mdc800_rs232_sendCommand) receiving commit fails.\n"); fault=1; } } if (fault) return GP_ERROR_IO; return GP_OK; }