📄 libvisca.c
字号:
/* * VISCA(tm) Camera Control Library * Copyright (C) 2002 Damien Douxchamps * * Written by Damien Douxchamps <douxchamps@ieee.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "libvisca.h"/********************************//* PRIVATE FUNCTIONS *//********************************/void_VISCA_append_byte(VISCAPacket_t *packet, unsigned char byte){ packet->bytes[packet->length]=byte; (packet->length)++;}void_VISCA_init_packet(VISCAPacket_t *packet){ // we start writing at byte 1, the first byte will be filled by the // packet sending function. This function will also append a terminator. packet->length=1;}unsigned int_VISCA_send_packet(VISCAInterface_t *interface, VISCACamera_t *camera, VISCAPacket_t *packet){#ifdef WIN DWORD iBytesWritten; static long bytesTogether = 0; BOOL rVal = 0; DWORD errors; COMSTAT stat; int nTrials;#else int err;#endif // check data: if ((interface->address>7)||(camera->address>7)||(interface->broadcast>1)) { fprintf(stderr,"(%s): Invalid header parameters\n",__FILE__); fprintf(stderr," %d %d %d \n",interface->address,camera->address,interface->broadcast); return VISCA_FAILURE; } // build header: packet->bytes[0]=0x80; packet->bytes[0]|=(interface->address << 4); if (interface->broadcast>0) { packet->bytes[0]|=(interface->broadcast << 3); packet->bytes[0]&=0xF8; } else packet->bytes[0]|=camera->address; // append footer _VISCA_append_byte(packet,VISCA_TERMINATOR);#ifdef WIN for (nTrials = 0; nTrials < 3 && rVal == 0; nTrials++) { if (nTrials > 0) ClearCommError(interface->port_fd, &errors, &stat); rVal = WriteFile(interface->port_fd, &packet->bytes, packet->length, &iBytesWritten, NULL); } if ( iBytesWritten < packet->length ) { DWORD lastError = GetLastError(); return VISCA_FAILURE; } else { bytesTogether += iBytesWritten; return VISCA_SUCCESS; }#else err=write(interface->port_fd, &packet->bytes, packet->length); if ( err < packet->length ) return VISCA_FAILURE; else return VISCA_SUCCESS;#endif}unsigned int_VISCA_get_packet(VISCAInterface_t *interface){ int bytes_read; int pos=0;#ifdef WIN DWORD iBytesRead;#endif // wait for message#ifdef WIN ReadFile(interface->port_fd, interface->ibuf, 1, &iBytesRead, NULL); while (interface->ibuf[pos]!=VISCA_TERMINATOR) { pos++; ReadFile(interface->port_fd, interface->ibuf + pos, 1, &iBytesRead, NULL); }#else ioctl(interface->port_fd, FIONREAD, &(interface->bytes)); while (interface->bytes==0) { usleep(0); ioctl(interface->port_fd, FIONREAD, &(interface->bytes)); } // get octets one by one bytes_read=read(interface->port_fd, interface->ibuf, 1); while (interface->ibuf[pos]!=VISCA_TERMINATOR) { pos++; bytes_read=read(interface->port_fd, &interface->ibuf[pos], 1); usleep(0); }#endif interface->bytes=pos+1; return VISCA_SUCCESS;}unsigned int_VISCA_get_reply(VISCAInterface_t *interface, VISCACamera_t *camera){ // first message: ------------------- _VISCA_get_packet(interface); interface->type=interface->ibuf[1]&0xF0; // skip ack messages while (interface->type==VISCA_RESPONSE_ACK) { _VISCA_get_packet(interface); interface->type=interface->ibuf[1]&0xF0; } switch (interface->type) { case VISCA_RESPONSE_CLEAR: return VISCA_SUCCESS; break; case VISCA_RESPONSE_ADDRESS: return VISCA_SUCCESS; break; case VISCA_RESPONSE_COMPLETED: return VISCA_SUCCESS; break; case VISCA_RESPONSE_ERROR: return VISCA_SUCCESS; break; default: return VISCA_FAILURE; break; }}unsigned int_VISCA_send_packet_with_reply(VISCAInterface_t *interface, VISCACamera_t *camera, VISCAPacket_t *packet){ if (_VISCA_send_packet(interface,camera,packet)!=VISCA_SUCCESS) return VISCA_FAILURE; if (_VISCA_get_reply(interface,camera)!=VISCA_SUCCESS) return VISCA_FAILURE; else return VISCA_SUCCESS; }/****************************************************************************//* PUBLIC FUNCTIONS *//****************************************************************************//***********************************//* SYSTEM FUNCTIONS *//***********************************/unsigned intVISCA_open_serial(VISCAInterface_t *interface, char *device_name){#ifdef WIN BOOL m_bPortReady; HANDLE m_hCom; DCB m_dcb; m_hCom = CreateFile(device_name, GENERIC_READ | GENERIC_WRITE, 0, // exclusive access NULL, // no security OPEN_EXISTING, 0, // no overlapped I/O NULL); // null template // Check the returned handle for INVALID_HANDLE_VALUE and then set the buffer sizes. if (m_hCom == INVALID_HANDLE_VALUE) { fprintf(stderr, "(%s): cannot open serial device %s\n", __FILE__, device_name); interface->port_fd = NULL; return VISCA_FAILURE; } m_bPortReady = SetupComm(m_hCom, 4, 4); // set buffer sizes // Port settings are specified in a Data Communication Block (DCB). The easiest way to initialize a DCB is to call GetCommState to fill in its default values, override the values that you want to change and then call SetCommState to set the values. m_bPortReady = GetCommState(m_hCom, &m_dcb); m_dcb.BaudRate = 9600; m_dcb.ByteSize = 8; m_dcb.Parity = NOPARITY; m_dcb.StopBits = ONESTOPBIT; m_dcb.fAbortOnError = TRUE; m_bPortReady = SetCommState(m_hCom, &m_dcb); // If all of these API's were successful then the port is ready for use. interface->port_fd = m_hCom; interface->address = 0;#else int fd; fd = open(device_name, O_RDWR | O_NDELAY | O_NOCTTY); if (fd == -1) { fprintf(stderr,"(%s): cannot open serial device %s\n",__FILE__,device_name); interface->port_fd=-1; return VISCA_FAILURE; } else { fcntl(fd, F_SETFL,0); /* Setting port parameters */ tcgetattr(fd, &interface->options); /* control flags */ cfsetispeed(&interface->options,B9600); /* 9600 Bds */ interface->options.c_cflag &= ~PARENB; /* No parity */ interface->options.c_cflag &= ~CSTOPB; /* */ interface->options.c_cflag &= ~CSIZE; /* 8bit */ interface->options.c_cflag |= CS8; /* */ interface->options.c_cflag &= ~CRTSCTS; /* No hdw ctl */ /* local flags */ interface->options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* raw input */ /* input flags */ interface->options.c_iflag &= ~(INPCK | ISTRIP); /* no parity */ interface->options.c_iflag &= ~(IXON | IXOFF | IXANY); /* no soft ctl */ /* output flags */ interface->options.c_oflag &= ~OPOST; /* raw output */ tcsetattr(fd, TCSANOW, &interface->options); } interface->port_fd = fd; interface->address=0;#endif return VISCA_SUCCESS;}unsigned intVISCA_close_serial(VISCAInterface_t *interface){#ifdef WIN if (interface->port_fd != NULL) { CloseHandle(interface->port_fd); interface->port_fd = NULL; return VISCA_SUCCESS; } else return VISCA_FAILURE;#else if (interface->port_fd!=-1) { close(interface->port_fd); interface->port_fd = -1; return VISCA_SUCCESS; } else return VISCA_FAILURE;#endif}unsigned intVISCA_set_address(VISCAInterface_t *interface, int *camera_num){ VISCAPacket_t packet; int backup; VISCACamera_t camera; /* dummy camera struct */ camera.address=0; backup=interface->broadcast; _VISCA_init_packet(&packet); _VISCA_append_byte(&packet,0x30); _VISCA_append_byte(&packet,0x01); interface->broadcast=1; if (_VISCA_send_packet(interface, &camera, &packet)!=VISCA_SUCCESS) { interface->broadcast=backup; return VISCA_FAILURE; } else interface->broadcast=backup; if (_VISCA_get_reply(interface, &camera)!=VISCA_SUCCESS) return VISCA_FAILURE; else { /* We parse the message from the camera here */ /* We expect to receive 4*camera_num bytes, every packet should be 88 30 0x FF, x being the camera id+1. The number of cams will thus be ibuf[bytes-2]-1 */ if ((interface->bytes & 0x11)!=0) /* check multiple of 4 */ return VISCA_FAILURE; else { *camera_num=interface->ibuf[interface->bytes-2]-1; if ((*camera_num==0)||(*camera_num>7)) return VISCA_FAILURE; else return VISCA_SUCCESS; } } }unsigned intVISCA_clear(VISCAInterface_t *interface, VISCACamera_t *camera){ VISCAPacket_t packet; _VISCA_init_packet(&packet); _VISCA_append_byte(&packet,0x01); _VISCA_append_byte(&packet,0x00); _VISCA_append_byte(&packet,0x01); if (_VISCA_send_packet(interface, camera, &packet)!=VISCA_SUCCESS) return VISCA_FAILURE; else if (_VISCA_get_reply(interface, camera)!=VISCA_SUCCESS) return VISCA_FAILURE; else return VISCA_SUCCESS;}unsigned intVISCA_get_camera_info(VISCAInterface_t *interface, VISCACamera_t *camera){ VISCAPacket_t packet;#ifdef WIN DWORD iBytesWritten;#endif packet.bytes[0]=0x80 | camera->address; packet.bytes[1]=0x09; packet.bytes[2]=0x00; packet.bytes[3]=0x02; packet.bytes[4]=VISCA_TERMINATOR; packet.length=5;#ifdef WIN WriteFile(interface->port_fd, packet.bytes, packet.length, &iBytesWritten, NULL);#else write(interface->port_fd, packet.bytes, packet.length);#endif if (_VISCA_get_reply(interface, camera)!=VISCA_SUCCESS) return VISCA_FAILURE; if (interface->bytes!= 10) /* we expect 10 bytes as answer */ return VISCA_FAILURE; else { camera->vendor=(interface->ibuf[2]<<8) + interface->ibuf[3]; camera->model=(interface->ibuf[4]<<8) + interface->ibuf[5]; camera->rom_version=(interface->ibuf[6]<<8) + interface->ibuf[7]; camera->socket_num=interface->ibuf[8]; return VISCA_SUCCESS; }}/***********************************//* COMMAND FUNCTIONS *//***********************************/unsigned intVISCA_set_power(VISCAInterface_t *interface, VISCACamera_t *camera, UInt8_t power){ VISCAPacket_t packet; _VISCA_init_packet(&packet); _VISCA_append_byte(&packet, VISCA_COMMAND); _VISCA_append_byte(&packet, VISCA_CATEGORY_CAMERA1); _VISCA_append_byte(&packet, VISCA_POWER); _VISCA_append_byte(&packet, power); return _VISCA_send_packet_with_reply(interface, camera, &packet);}unsigned intVISCA_set_keylock(VISCAInterface_t *interface, VISCACamera_t *camera, UInt8_t power){ VISCAPacket_t packet; _VISCA_init_packet(&packet); _VISCA_append_byte(&packet, VISCA_COMMAND); _VISCA_append_byte(&packet, VISCA_CATEGORY_CAMERA1); _VISCA_append_byte(&packet, VISCA_KEYLOCK); _VISCA_append_byte(&packet, power); return _VISCA_send_packet_with_reply(interface, camera, &packet);}unsigned intVISCA_set_camera_id(VISCAInterface_t *interface, VISCACamera_t *camera, UInt16_t id){ VISCAPacket_t packet; _VISCA_init_packet(&packet); _VISCA_append_byte(&packet, VISCA_COMMAND); _VISCA_append_byte(&packet, VISCA_CATEGORY_CAMERA1); _VISCA_append_byte(&packet, VISCA_ID); _VISCA_append_byte(&packet, (id & 0xF000) >> 12); _VISCA_append_byte(&packet, (id & 0x0F00) >> 8); _VISCA_append_byte(&packet, (id & 0x00F0) >> 4); _VISCA_append_byte(&packet, (id & 0x000F)); return _VISCA_send_packet_with_reply(interface, camera, &packet);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -