//set data bit , stop bit and checksum bit int set_Parity(int fd, int databits, int stopbits, int parity) { struct termios options; if (tcgetattr(fd, &options) != 0) { perror("SetupSerial 1"); return (FALSE); } options.c_cflag &= ~CSIZE; switch (databits) { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr, "Unsupported data size\n"); return (FALSE); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; //Clear parity enable options.c_iflag &= ~INPCK; // Enable parity checking break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); //set as odd check options.c_iflag |= INPCK; //Disnable parity check break; case 'e': case 'E': options.c_cflag |= PARENB; //Enable parity options.c_cflag &= ~PARODD; options.c_iflag |= INPCK; //Disnable parity checking break; case 'S': case 's': //as no parity options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: fprintf(stderr, "Unsupported parity\n"); return (FALSE); } switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr, "Unsupported stop bits\n"); return (FALSE); } //Set input parity option if (parity != 'n') { options.c_iflag |= INPCK; } options.c_cc[VTIME] = 150; // 15 seconds options.c_cc[VMIN] = 0; tcflush(fd, TCIFLUSH); // Update the options and do it NOW if (tcsetattr(fd, TCSANOW, &options) != 0) { perror("SetupSerial 3"); return (FALSE); } return (TRUE); }
serial_port uart_open(const char* pcPortName) { serial_port_unix* sp = malloc(sizeof(serial_port_unix)); if (sp == 0) return INVALID_SERIAL_PORT; if (memcmp(pcPortName, "tcp:", 4) == 0) { struct addrinfo *addr = NULL, *rp; char *addrstr = strdup(pcPortName + 4); if (addrstr == NULL) { printf("Error: strdup\n"); return INVALID_SERIAL_PORT; } char *colon = strrchr(addrstr, ':'); char *portstr; // Set time-out to 300 miliseconds only for TCP port timeout.tv_usec = 300000; if (colon) { portstr = colon + 1; *colon = '\0'; } else portstr = "7901"; struct addrinfo info; memset (&info, 0, sizeof(info)); info.ai_socktype = SOCK_STREAM; int s = getaddrinfo(addrstr, portstr, &info, &addr); if (s != 0) { printf("Error: getaddrinfo: %s\n", gai_strerror(s)); return INVALID_SERIAL_PORT; } int sfd; for (rp = addr; rp != NULL; rp = rp->ai_next) { sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd == -1) continue; if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) break; close(sfd); } if (rp == NULL) { /* No address succeeded */ printf("Error: Could not connect\n"); return INVALID_SERIAL_PORT; } freeaddrinfo(addr); free(addrstr); sp->fd = sfd; int one = 1; setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); return sp; } sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if(sp->fd == -1) { uart_close(sp); return INVALID_SERIAL_PORT; } // Finally figured out a way to claim a serial port interface under unix // We just try to set a (advisory) lock on the file descriptor struct flock fl; fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_pid = getpid(); // Does the system allows us to place a lock on this file descriptor if (fcntl(sp->fd, F_SETLK, &fl) == -1) { // A conflicting lock is held by another process free(sp); return CLAIMED_SERIAL_PORT; } // Try to retrieve the old (current) terminal info struct if(tcgetattr(sp->fd,&sp->tiOld) == -1) { uart_close(sp); return INVALID_SERIAL_PORT; } // Duplicate the (old) terminal info struct sp->tiNew = sp->tiOld; // Configure the serial port sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; sp->tiNew.c_iflag = IGNPAR; sp->tiNew.c_oflag = 0; sp->tiNew.c_lflag = 0; // Block until n bytes are received sp->tiNew.c_cc[VMIN] = 0; // Block until a timer expires (n * 100 mSec.) sp->tiNew.c_cc[VTIME] = 0; // Try to set the new terminal info struct if(tcsetattr(sp->fd,TCSANOW,&sp->tiNew) == -1) { uart_close(sp); return INVALID_SERIAL_PORT; } // Flush all lingering data that may exist tcflush(sp->fd, TCIOFLUSH); return sp; }
static int set_com_state(int fd, uart_com_state_t* com) { struct termios tio; // read current state if (tcgetattr(fd, &tio) < 0) { DEBUGF("unable to read com state: %s", strerror(errno)); return -1; } // On Mac os X IOSSIOSPEED can be used to set "non-traditional baud rate" // From "IOKit/serial/ioss.h" cfsetispeed(&tio, to_speed(com->ibaud)); cfsetospeed(&tio, to_speed(com->obaud)); // update from state switch(com->parity) { case UART_PARITY_NONE: tio.c_iflag &= ~PARMRK; tio.c_cflag &= ~PARENB; break; case UART_PARITY_ODD: // odd tio.c_iflag &= ~PARMRK; tio.c_cflag |= PARODD; tio.c_cflag |= PARENB; break; case UART_PARITY_EVEN: // even tio.c_iflag &= ~PARMRK; tio.c_cflag &= ~PARODD; tio.c_cflag |= PARENB; break; case UART_PARITY_MARK: // mark (FIXME) tio.c_iflag |= PARMRK; tio.c_cflag |= PARENB; break; case UART_PARITY_SPACE: // space (FIXME) tio.c_iflag &= ~PARMRK; tio.c_cflag &= ~PARENB; break; default: break; } if (com->stopb == 1) tio.c_cflag &= ~CSTOPB; else if (com->stopb == 2) tio.c_cflag |= CSTOPB; tio.c_cflag &= ~CSIZE; switch(com->csize) { case 5: tio.c_cflag |= CS5; break; case 6: tio.c_cflag |= CS6; break; case 7: tio.c_cflag |= CS7; break; case 8: tio.c_cflag |= CS8; break; default: break; } // Set the buffer number of bytes buffered before interrupt if (com->bufsz > 255) tio.c_cc[VMIN] = 255; else tio.c_cc[VMIN] = com->bufsz; // Set the max time to buffer bytes if (com->buftm > 25500) // 25500 ms = 25.5 sec tio.c_cc[VTIME] = 255; else tio.c_cc[VTIME] = com->buftm / 100; tio.c_cc[VSTART] = com->xonchar; tio.c_cc[VSTOP] = com->xoffchar; // input flow control UPD_BIT(tio.c_iflag, IXOFF, (com->iflow & UART_SW)); #if defined(CRTS_IFLOW) UPD_BIT(tio.c_cflag, CRTS_IFLOW, (com->iflow & UART_RTS)); #endif #if defined(CDTR_IFLOW) UPD_BIT(tio.c_cflag, CDTR_IFLOW, (com->iflow & UART_DTR)); #endif // output flow control UPD_BIT(tio.c_iflag, IXON, (com->oflow & UART_SW)); #if defined(CCTS_OFLOW) UPD_BIT(tio.c_cflag, CCTS_OFLOW, (com->oflow & UART_CTS)); #endif #if defined(CDSR_OFLOW) UPD_BIT(tio.c_cflag, CDSR_OFLOW, (com->oflow & UART_DSR)); #endif #if defined(CCAR_OFLOW) UPD_BIT(tio.c_cflag, CCAR_OFLOW, (com->oflow & UART_CD)); #endif #if defined(CRTSCTS) if ((com->iflow & UART_RTS) && (com->oflow & UART_CTS)) tio.c_cflag |= CRTSCTS; else if (!(com->iflow & UART_RTS) && !(com->oflow & UART_CTS)) tio.c_cflag &= ~CRTSCTS; #endif // ignore break condition tio.c_iflag |= IGNBRK; // local line + enable receiver tio.c_cflag |= (CLOCAL | CREAD); // raw input processing tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN); // no output processing tio.c_oflag &= ~(OPOST); // do NOT hangup-on-close, need? we keep one slave open tio.c_cflag &= ~HUPCL; tcflush(fd, TCIFLUSH); return tcsetattr(fd, TCSANOW, &tio); }
/* ARGSUSED */ static void oob(int signo __unused) { struct termios tty; int atmark, n, rcvd; char waste[BUFSIZ], mark; rcvd = 0; while (recv(rem, &mark, 1, MSG_OOB) < 0) { switch (errno) { case EWOULDBLOCK: /* * Urgent data not here yet. It may not be possible * to send it yet if we are blocked for output and * our input buffer is full. */ if (rcvcnt < (int)sizeof(rcvbuf)) { n = read(rem, rcvbuf + rcvcnt, sizeof(rcvbuf) - rcvcnt); if (n <= 0) return; rcvd += n; } else { n = read(rem, waste, sizeof(waste)); if (n <= 0) return; } continue; default: return; } } if (mark & TIOCPKT_WINDOW) { /* Let server know about window size changes */ (void)kill(ppid, SIGUSR1); } if (!eight && (mark & TIOCPKT_NOSTOP)) { (void)tcgetattr(0, &tty); tty.c_iflag &= ~IXON; (void)tcsetattr(0, TCSANOW, &tty); } if (!eight && (mark & TIOCPKT_DOSTOP)) { (void)tcgetattr(0, &tty); tty.c_iflag |= (deftty.c_iflag & IXON); (void)tcsetattr(0, TCSANOW, &tty); } if (mark & TIOCPKT_FLUSHWRITE) { (void)tcflush(1, TCIOFLUSH); for (;;) { if (ioctl(rem, SIOCATMARK, &atmark) < 0) { warn("ioctl"); break; } if (atmark) break; n = read(rem, waste, sizeof (waste)); if (n <= 0) break; } /* * Don't want any pending data to be output, so clear the recv * buffer. If we were hanging on a write when interrupted, * don't want it to restart. If we were reading, restart * anyway. */ rcvcnt = 0; longjmp(rcvtop, 1); } /* oob does not do FLUSHREAD (alas!) */ /* * If we filled the receive buffer while a read was pending, longjmp * to the top to restart appropriately. Don't abort a pending write, * however, or we won't know how much was written. */ if (rcvd && rcvstate == READING) longjmp(rcvtop, 1); }
BOOL BT_InitDevice( HANDLE hComPortFile, PBYTE ucNvRamData, DWORD dwBaud, DWORD dwHostBaud, DWORD dwUseFlowControl, SETUP_UART_PARAM setup_uart_param ) { DWORD dwStatus; LPBYTE pbPatchExtBin = NULL; DWORD dwPatchExtLen = 0; FILE* pPatchExtFile = NULL; LPBYTE pbPatchBin = NULL; DWORD dwPatchLen = 0; FILE* pPatchFile = NULL; printf("BT_InitDevice\r\n"); #ifndef MTK_COMBO_SUPPORT tcflush(hComPortFile, TCIOFLUSH); pSetup_uart_param = setup_uart_param; if(pSetup_uart_param == NULL){ printf("UART setup callback is null\r\n"); return FALSE; } printf("BT load firmware patch\r\n"); #if BT_PATCH_EXT_ENABLE pPatchExtFile = fopen(BT_UPDATE_PATCH_EXT_FILE_NAME, "rb"); /* if there is no adhoc file, use built-in patch file under system etc firmware */ if(pPatchExtFile == NULL){ pPatchExtFile = fopen(BT_BUILT_IN_PATCH_EXT_FILE_NAME, "rb"); if(pPatchExtFile != NULL) { printf("Open %s\r\n", BT_BUILT_IN_PATCH_EXT_FILE_NAME); } else { printf("Can't get valid patch ext file\r\n"); } } else { printf("Open %s\r\n", BT_UPDATE_PATCH_EXT_FILE_NAME); } /* file exists */ if(pPatchExtFile != NULL){ if(fseek(pPatchExtFile, 0, SEEK_END) != 0){ printf("fseek patch ext file fails errno: %d\n", errno); } else{ long lFileLen = 0; lFileLen = ftell(pPatchExtFile); if (lFileLen > 0){ printf("Patch ext file size %d\n", (int)lFileLen); rewind(pPatchExtFile); pbPatchExtBin = (unsigned char*)malloc(lFileLen); if (pbPatchExtBin){ size_t szReadLen = fread(pbPatchExtBin, 1, lFileLen, pPatchExtFile); dwPatchExtLen = szReadLen; if(szReadLen != (size_t)lFileLen){ printf("fread patch ext len error, file len: %d, read len: %d\n", (int)lFileLen, (int)szReadLen); free(pbPatchExtBin); pbPatchExtBin = NULL; dwPatchExtLen = 0; } }else{ printf("Allocate patch ext memory fails\n"); } }else{ printf("Patch ext error len %d\n", (int)lFileLen); } } } #endif /* Use data directory first. for future update test convinience */ pPatchFile = fopen(BT_UPDATE_PATCH_FILE_NAME, "rb"); /* if there is no adhoc file, use built-in patch file under system etc firmware */ if(pPatchFile == NULL){ pPatchFile = fopen(BT_BUILT_IN_PATCH_FILE_NAME, "rb"); if(pPatchFile != NULL) { printf("Open %s\r\n", BT_BUILT_IN_PATCH_FILE_NAME); } else { printf("Can't get valid patch file\r\n"); } } else { printf("Open %s\r\n", BT_UPDATE_PATCH_FILE_NAME); } /* file exists */ if(pPatchFile != NULL){ if(fseek(pPatchFile, 0, SEEK_END) != 0){ printf("fseek patch file fails errno: %d\n", errno); } else{ long lFileLen = 0; lFileLen = ftell(pPatchFile); if (lFileLen > 0){ printf("Patch file size %d\n", (int)lFileLen); /* back to file beginning */ rewind(pPatchFile); printf ("Rewinded\n"); pbPatchBin = (unsigned char*)malloc(lFileLen); if(pbPatchBin){ size_t szReadLen = 0; szReadLen = fread(pbPatchBin, 1, lFileLen, pPatchFile); dwPatchLen = szReadLen; if(szReadLen != (size_t)lFileLen){ printf("fread patch len error, file len: %d, read len: %d\n", (int)lFileLen, (int)szReadLen); free(pbPatchBin); pbPatchBin = NULL; dwPatchLen = 0; } }else{ printf("Allocate patch memory fails\n"); } }else{ printf("Patch error len %d\n", (int)lFileLen); } } } #endif printf ("GORM_INIT\n"); /* Invoke HCI transport entrance */ dwStatus = GORM_Init( hComPortFile, pbPatchExtBin, //patch ext dwPatchExtLen, pbPatchBin, //patch dwPatchLen, ucNvRamData, dwBaud, dwHostBaud, dwUseFlowControl ); #ifndef MTK_COMBO_SUPPORT if(pbPatchExtBin){ free(pbPatchExtBin); pbPatchExtBin = NULL; } if(pPatchExtFile){ fclose(pPatchExtFile); pPatchExtFile = NULL; } if(pbPatchBin){ free(pbPatchBin); pbPatchBin = NULL; } if(pPatchFile){ fclose(pPatchFile); pPatchFile = NULL; } #endif if(dwStatus != 0 ){ printf("GORM fails return code %d\r\n", (int)dwStatus); return FALSE; } return TRUE; }
void serial_flush () { tcflush (serialfd, TCIFLUSH); }
/* * sndpkt(r, x, y) - send packet and receive response * * This routine sends a command frame, which consists of all except the * preamble octets PR-PR. It then listens for the response frame and * returns the payload to the caller. The routine checks for correct * response header format; that is, the length of the response vector * returned to the caller must be at least 2 and the RE and TX octets * must be interchanged; otherwise, the operation is retried up to * the number of times specified in a global variable. * * The trace function, which is enabled by the P_TRACE bit of the global * flags variable, prints all characters received or echoed on the bus * preceded by a T (transmit) or R (receive). The P_ERMSG bit of the * flags variable enables printing of bus error messages. * * Note that the first octet sent is a PAD in order to allow time for * the radio to flush its receive buffer after sending the previous * response. Even with this precaution, some of the older radios * occasionally fail to receive a command and it has to be sent again. */ static int sndpkt( /* returns octet count */ int fd, /* file descriptor */ int r, /* radio address */ u_char *cmd, /* command vector */ u_char *rsp /* response vector */ ) { int i, j, temp; (void)tcflush(fd, TCIOFLUSH); for (i = 0; i < RETRY; i++) { state = S_IDLE; /* * Transmit packet. */ if (flags & P_TRACE) printf("icom T:"); sndoctet(fd, PAD); /* send header */ sndoctet(fd, PR); sndoctet(fd, PR); sndoctet(fd, r); sndoctet(fd, TX); for (j = 0; j < BMAX; j++) { /* send body */ if (sndoctet(fd, cmd[j]) == FI) break; } while (rcvoctet(fd) != FI); /* purge echos */ if (cmd[0] == V_FREQT || cmd[0] == V_MODET) return (0); /* shortcut for broadcast */ /* * Receive packet. First, delete all characters * preceeding a PR, then discard all PRs. Check that the * RE and TX fields are correctly interchanged, then * copy the remaining data and FI to the user buffer. */ if (flags & P_TRACE) printf("\nicom R:"); j = 0; while ((temp = rcvoctet(fd)) != FI) { switch (state) { case S_IDLE: if (temp != PR) continue; state = S_HDR; break; case S_HDR: if (temp == PR) { continue; } else if (temp != TX) { if (flags & P_ERMSG) printf( "icom: TX error\n"); state = S_ERROR; } state = S_TX; break; case S_TX: if (temp != r) { if (flags & P_ERMSG) printf( "icom: RE error\n"); state = S_ERROR; } state = S_DATA; break; case S_DATA: if (j >= BMAX ) { if (flags & P_ERMSG) printf( "icom: buffer overrun\n"); state = S_ERROR; j = 0; } rsp[j++] = (u_char)temp; break; case S_ERROR: break; } } if (flags & P_TRACE) printf("\n"); if (j > 0) { rsp[j++] = FI; return (j); } } if (flags & P_ERMSG) printf("icom: retries exceeded\n"); return (0); }
void* uart4_checker(void *ptr){ //set up sart/stop bit and 115200 baud struct termios config; memset(&config,0,sizeof(config)); config.c_iflag=0; config.c_iflag=0; config.c_oflag=0; config.c_cflag= CS8|CREAD|CLOCAL; // 8n1, see termios.h for more info config.c_lflag=0; config.c_cc[VTIME]=0; // no timeout condition config.c_cc[VMIN]=1; // only return if something is in the buffer // open for blocking reads if ((tty4_fd = open (UART4_PATH, O_RDWR | O_NOCTTY)) < 0) { printf("error opening uart4\n"); } // Spektrum and Orange recievers are 115200 baud if(cfsetispeed(&config, B115200) < 0) { printf("cannot set uart4 baud rate\n"); return NULL; } if(tcsetattr(tty4_fd, TCSAFLUSH, &config) < 0) { printf("cannot set uart4 attributes\n"); return NULL; } while(1){ char buf[64]; // large serial buffer to catch doubled up packets int i,j; memset(&buf, 0, sizeof(buf)); // clear buffer i = read(tty4_fd,&buf,sizeof(buf)); // blocking read if(i<0){ #ifdef DEBUG_DSM2 printf("error, read returned -1\n"); #endif goto end; } else if(i>16){ #ifdef DEBUG_DSM2 printf("error: read too many bytes.\n"); #endif goto end; } //incomplete packet read, wait and read the rest of the buffer else if(i<16){ // packet takes about 1.4ms at 115200 baud. sleep for 2.0 usleep(2000); //read the rest j = read(tty4_fd,&buf[i],sizeof(buf)-i); // blocking read //if the rest of the packet failed to arrive, error if(j+i != 16){ #ifdef DEBUG_DSM2 printf("error: wrong sized packet\n"); #endif goto end; } } // if we've gotten here, we have a 16 byte packet tcflush(tty4_fd,TCIOFLUSH); #ifdef DEBUG_DSM2 printf("read %d bytes, ", j+i); #endif #ifdef DEBUG_DSM2_RAW printf("read %d bytes, ", j+i); for(i=0; i<8; i++){ printf(byte_to_binary(buf[i*2])); printf(" "); printf(byte_to_binary(buf[(i*2)+1])); printf(" "); } printf("\n"); #endif // Next we must check if the packets are 10-bit 1024/22ms mode // or 11bit 2048/11ms mode. read through and decide which one, then read int mode = 22; // start assuming 10-bit 1024 mode, 22ms unsigned char ch_id; int16_t value; // first check each channel id assuming 1024/22ms mode // where the channel id lives in 0b01111000 mask // if one doesn't make sense, must be using 2048/11ms mode for(i=1;i<=7;i++){ // last few words in buffer are often all 1's, ignore those if(buf[2*i]!=0xFF && buf[(2*i)+1]!=0xFF){ // grab channel id from first byte ch_id = (buf[i*2]&0b01111100)>>2; // maximum 9 channels, if the channel id exceeds that, // we must be reading it wrong, swap to 11ms mode if((ch_id+1)>9){ #ifdef DEBUG_DSM2 printf("2048/11ms "); #endif mode = 11; goto read_packet; } } } #ifdef DEBUG_DSM2 printf("1024/22ms "); #endif read_packet: // packet is 16 bytes, 8 words long // first word doesn't have channel data, so iterate through last 7 words for(i=1;i<=7;i++){ // in 8 and 9 ch radios, unused words are 0xFF // skip if one of them if(buf[2*i]!=0xFF || buf[(2*i)+1]!=0xFF){ // grab channel id from first byte // and value from both bytes if(mode == 22){ dsm2_frame_rate = 22; ch_id = (buf[i*2]&0b01111100)>>2; // grab value from least 11 bytes value = ((buf[i*2]&0b00000011)<<8) + buf[(2*i)+1]; value += 989; // shift range so 1500 is neutral } else if(mode == 11){ dsm2_frame_rate = 11; ch_id = (buf[i*2]&0b01111000)>>3; // grab value from least 11 bytes value = ((buf[i*2]&0b00000111)<<8) + buf[(2*i)+1]; // extra bit of precision means scale is off by factor of two // also add 989 to center channels around 1500 value = (value/2) + 989; }
// uncomment this define to print raw data for debugging // #define DEBUG_DSM2 void* uart4_checker(void *ptr){ //set up sart/stop bit and 115200 baud struct termios config; memset(&config,0,sizeof(config)); config.c_iflag=0; config.c_iflag=0; config.c_oflag=0; config.c_cflag= CS8|CREAD|CLOCAL; // 8n1, see termios.h for more info config.c_lflag=0; config.c_cc[VTIME]=0; // no timeout condition config.c_cc[VMIN]=1; // only return if something is in the buffer // open for blocking reads if ((tty4_fd = open (UART4_PATH, O_RDWR | O_NOCTTY)) < 0) { printf("error opening uart4\n"); } // Spektrum and Oragne recievers are 115200 baud if(cfsetispeed(&config, B115200) < 0) { printf("cannot set uart4 baud rate\n"); return NULL; } if(tcsetattr(tty4_fd, TCSAFLUSH, &config) < 0) { printf("cannot set uart4 attributes\n"); return NULL; } while(1){ char buf[64]; // large serial buffer to catch doubled up packets int i,j; memset(&buf, 0, sizeof(buf)); // clear buffer i = read(tty4_fd,&buf,sizeof(buf)); // blocking read #ifdef DEBUG_DSM2 printf("recieved %d bytes, ", i); #endif if(i<0){ #ifdef DEBUG_DSM2 printf("error, read returned -1\n"); #endif goto end; } else if(i>16){ #ifdef DEBUG_DSM2 printf("error: read too many bytes.\n"); #endif goto end; } //incomplete packet read, wait and read the rest of the buffer else if(i<16){ // packet takes about 1.4ms at 115200 baud. sleep for 2.0 usleep(2000); //read the rest j = read(tty4_fd,&buf[i],sizeof(buf)-i); // blocking read #ifdef DEBUG_DSM2 printf("then %d bytes, ", j); #endif //if the rest of the packet failed to arrive, error if(j+i != 16){ #ifdef DEBUG_DSM2 printf("error: wrong sized packet\n"); #endif goto end; } } // if we've gotten here, we have a 16 byte packet // first check if it's from an Orange TX and read channels in order // 8 and 9 ch dsmx radios end in 0xFF too, but those are also 0xFF // on bytes 5-13 if(buf[14]==0xFF && buf[15]==0xFF && buf[13]!=0xFF){ // i from 1 to 7 to get last 6 words of packet // first word contains lost frames so skip it for(i=1;i<=7;i++){ int16_t value; // merge bytes value = buf[i*2]<<8 ^ buf[(i*2)+1]; // on Orange tx, each raw channel is 1000 larger than the last // remove this extra 1000 to get back to microseconds value -= 1000*(i-2); // rc_channels is 0 indexed, so i-1 rc_channels[i-1] = value; #ifdef DEBUG_DSM2 printf("%d %d ", i, rc_channels[i-1]); #endif } } // must be a Spektrum packet instead, read a channel at a time else{ unsigned char ch_id; int16_t value; #ifdef DEBUG_DSM2 printf("ch_id: "); #endif // packet is 16 bytes, 8 words long // first word doesn't have channel data, so iterate through last 7 for(i=1;i<=7;i++){ // in dsmX 8 and 9 ch radios, unused words are 0xFF // skip if one of them if(buf[2*i]!=0xFF || buf[(2*i)+1]!=0xFF){ // grab channel id from first byte ch_id = (buf[i*2]&0b01111100)>>2; // grab value from least 11 bytes value = ((buf[i*2]&0b00000011)<<8) + buf[(2*i)+1]; value += 1000; // shift range so 1500 is neutral #ifdef DEBUG_DSM2 printf("%d %d ",ch_id,value); // printf(byte_to_binary(buf[i*2])); // printf(" "); // printf(byte_to_binary(buf[(i*2)+1])); // printf(" "); #endif if(ch_id>9){ #ifdef DEBUG_DSM2 printf("error: bad channel id\n"); #endif goto end; } // throttle is channel 1 always // ch_id is 0 indexed, though // and rc_channels is 0 indexed, so also 0 rc_channels[ch_id] = value; } } } // indicate new a new packet has been processed new_dsm2_flag=1; #ifdef DEBUG_DSM2 printf("\n"); #endif end: // wait and clear the buffer usleep(2000); tcflush(tty4_fd,TCIOFLUSH); // packets arrive in every 11ms or 22ms // to account for possible wait above, sleep for 6ms usleep(6000); }
/*! Open and initialize the Servolens serial link at 9600 bauds, 7 data bits, even parity, 1 stop bit. The cariage return mode is not active, that means that each character is directly read without waitong for a cariage return. \param port : Serial device like /dev/ttyS0 or /dev/ttya. \exception vpRobotException::communicationError : If cannot open Servolens serial port or intialize the serial link. \sa close() */ void vpServolens::open(const char *port) { if (! isinit) { struct termios info; printf("\nOpen the Servolens serial port \"%s\"\n", port); if ((this->remfd=::open(port, O_RDWR|O_NONBLOCK)) < 0) { vpERROR_TRACE ("Cannot open Servolens serial port."); throw vpRobotException (vpRobotException::communicationError, "Cannot open Servolens serial port."); } // Lecture des parametres courants de la liaison serie. if (tcgetattr(this->remfd, &info) < 0) { ::close(this->remfd); vpERROR_TRACE ("Error using TCGETS in ioctl."); throw vpRobotException (vpRobotException::communicationError, "Error using TCGETS in ioctl"); } // // Configuration de la liaison serie: // 9600 bauds, 1 bit de stop, parite paire, 7 bits de donnee // // Traitement sur les caracteres recus info.c_iflag = 0; info.c_iflag |= INLCR; // Traitement sur les caracteres envoyes sur la RS232. info.c_oflag = 0; // idem // Traitement des lignes info.c_lflag = 0; // Controle materiel de la liaison info.c_cflag = 0; info.c_cflag |= CREAD; // Validation reception info.c_cflag |= B9600 | CS7 | PARENB; // 9600 baus, 7 data, parite paire // Caracteres immediatement disponibles. // info.c_cc[VMIN] = 1; // info.c_cc[VTIME] = 0; if (tcsetattr(this->remfd, TCSANOW, &info) < 0) { ::close(this->remfd); vpERROR_TRACE ("Error using TCGETS in ioctl."); throw vpRobotException (vpRobotException::communicationError, "Error using TCGETS in ioctl"); } // Supprime tous les caracteres recus mais non encore lus par read() tcflush(this->remfd, TCIFLUSH); isinit = true; this->init(); // Try to get the position of the zoom to check if the lens is really connected unsigned int izoom; if (this->getPosition(vpServolens::ZOOM, izoom) == false) { vpERROR_TRACE ("Cannot dial with the servolens. Check if the serial link is connected."); throw vpRobotException (vpRobotException::communicationError, "Cannot dial with the servolens. Check if the serial link is connected."); } } }
static BOOL _purge(WINPR_COMM *pComm, const ULONG *pPurgeMask) { if ((*pPurgeMask & ~(SERIAL_PURGE_TXABORT | SERIAL_PURGE_RXABORT | SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_RXCLEAR)) > 0) { CommLog_Print(WLOG_WARN, "Invalid purge mask: 0x%lX\n", *pPurgeMask); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } /* FIXME: currently relying too much on the fact the server * sends a single IRP_MJ_WRITE or IRP_MJ_READ at a time * (taking care though that one IRP_MJ_WRITE and one * IRP_MJ_READ can be sent simultaneously) */ if (*pPurgeMask & SERIAL_PURGE_TXABORT) { /* Purges all write (IRP_MJ_WRITE) requests. */ if (eventfd_write(pComm->fd_write_event, FREERDP_PURGE_TXABORT) < 0) { if (errno != EAGAIN) { CommLog_Print(WLOG_WARN, "eventfd_write failed, errno=[%d] %s", errno, strerror(errno)); } assert(errno == EAGAIN); /* no reader <=> no pending IRP_MJ_WRITE */ } } if (*pPurgeMask & SERIAL_PURGE_RXABORT) { /* Purges all read (IRP_MJ_READ) requests. */ if (eventfd_write(pComm->fd_read_event, FREERDP_PURGE_RXABORT) < 0) { if (errno != EAGAIN) { CommLog_Print(WLOG_WARN, "eventfd_write failed, errno=[%d] %s", errno, strerror(errno)); } assert(errno == EAGAIN); /* no reader <=> no pending IRP_MJ_READ */ } } if (*pPurgeMask & SERIAL_PURGE_TXCLEAR) { /* Purges the transmit buffer, if one exists. */ if (tcflush(pComm->fd, TCOFLUSH) < 0) { CommLog_Print(WLOG_WARN, "tcflush(TCOFLUSH) failure, errno=[%d] %s", errno, strerror(errno)); SetLastError(ERROR_CANCELLED); return FALSE; } } if (*pPurgeMask & SERIAL_PURGE_RXCLEAR) { /* Purges the receive buffer, if one exists. */ if (tcflush(pComm->fd, TCIFLUSH) < 0) { CommLog_Print(WLOG_WARN, "tcflush(TCIFLUSH) failure, errno=[%d] %s", errno, strerror(errno)); SetLastError(ERROR_CANCELLED); return FALSE; } } return TRUE; }
static int tty_connect(struct scpi_instrument *scpi) { struct termios ti; char strbuf[250]; ssize_t status; scpi->ttyfd = open(scpi->tty_path, O_RDWR | O_NOCTTY); if (scpi->ttyfd < 0) { print_output_sys(stderr, "%s: Can't open serial port: %s %s (%d)\n", __func__, scpi->tty_path, strerror(errno), errno); return -1; } tcflush(scpi->ttyfd, TCIOFLUSH); if (tcgetattr(scpi->ttyfd, &ti) < 0) { print_output_sys(stderr, strbuf, "%s: Can't get port settings: %s (%d)\n", __func__, strerror(errno), errno); close(scpi->ttyfd); scpi->ttyfd = -1; return -1; } #ifdef TTY_RAW_MODE cfmakeraw(&ti); ti.c_cc[VMIN] = 1; ti.c_cc[VTIME] = 0; #else ti.c_cflag |= ICANON; #endif ti.c_cflag |= CLOCAL; ti.c_cflag &= ~CRTSCTS; ti.c_cflag &= ~PARENB; ti.c_cflag &= ~PARODD; ti.c_cflag &= ~CSIZE; ti.c_cflag |= CS8; ti.c_cflag &= ~CSTOPB; ti.c_oflag &= ~OPOST; ti.c_iflag = ti.c_lflag = 0; cfsetospeed(&ti, B19200); /* We don't need that for USB-GPIB */ if (tcsetattr(scpi->ttyfd, TCSANOW, &ti) < 0) { print_output_sys(stderr, strbuf, "%s: Can't change port settings: %s (%d)\n", __func__, strerror(errno), errno); close(scpi->ttyfd); scpi->ttyfd = -1; return -1; } tcflush(scpi->ttyfd, TCIOFLUSH); #ifdef TTY_RAW_MODE if (fcntl(scpi->ttyfd, F_SETFL, fcntl(scpi->ttyfd, F_GETFL, 0) | O_NONBLOCK) < 0) { print_output_sys(stderr, "%s: Can't set non blocking mode: %s (%d)\n", __func__, strerror(errno), errno); close(scpi->ttyfd); scpi->ttyfd = -1; return -1; } #endif print_output_sys(stdout, "%s: GPIB tty: connecting to %s\n", __func__, scpi->tty_path); /* set up controller and GPIB address */ sprintf(strbuf, "++mode 1\n"); status = write(scpi->ttyfd, strbuf, strlen(strbuf)); if (status < 0) return -1; sprintf(strbuf, "++addr %d\n", scpi->gpib_addr); status = write(scpi->ttyfd, strbuf, strlen(strbuf)); if (status < 0) return -1; sprintf(strbuf, "++auto 1\n"); status = write(scpi->ttyfd, strbuf, strlen(strbuf)); if (status < 0) return -1; return 0; }
static void console_stty (void) { struct termios tty; int fd; if ((fd = console_open (O_RDWR | O_NOCTTY)) < 0) { initlog ("can't open console!"); return; } (void) tcgetattr (fd, &tty); tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; tty.c_cflag |= HUPCL | CLOCAL | CREAD; tty.c_cc[VINTR] = CINTR; tty.c_cc[VQUIT] = CQUIT; tty.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */ tty.c_cc[VKILL] = CKILL; tty.c_cc[VEOF] = CEOF; tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = 1; tty.c_cc[VSWTC] = _POSIX_VDISABLE; tty.c_cc[VSTART] = CSTART; tty.c_cc[VSTOP] = CSTOP; tty.c_cc[VSUSP] = CSUSP; tty.c_cc[VEOL] = _POSIX_VDISABLE; tty.c_cc[VREPRINT] = CREPRINT; tty.c_cc[VDISCARD] = CDISCARD; tty.c_cc[VWERASE] = CWERASE; tty.c_cc[VLNEXT] = CLNEXT; tty.c_cc[VEOL2] = _POSIX_VDISABLE; /* * Set pre and post processing */ tty.c_iflag = IGNPAR | ICRNL | IXON | IXANY; #ifdef IUTF8 /* Not defined on FreeBSD */ tty.c_iflag |= IUTF8; #endif /* IUTF8 */ tty.c_oflag = OPOST | ONLCR; tty.c_lflag = ISIG | ICANON | ECHO | ECHOCTL | ECHOPRT | ECHOKE; #if defined(SANE_TIO) && (SANE_TIO == 1) /* * Disable flow control (-ixon), ignore break (ignbrk), * and make nl/cr more usable (sane). */ tty.c_iflag |= IGNBRK; tty.c_iflag &= ~(BRKINT | INLCR | IGNCR | IXON); tty.c_oflag &= ~(OCRNL | ONLRET); #endif /* * Now set the terminal line. * We don't care about non-transmitted output data * and non-read input data. */ (void) tcsetattr (fd, TCSANOW, &tty); (void) tcflush (fd, TCIOFLUSH); (void) close (fd); }
void config_comm(int fd, int speed_baud_rate, char parity, int data_bits, int stop_bits) { int valid_baud_rate = 0; struct termios new_tc; memset(&new_tc, 0x00, sizeof(struct termios)); valid_baud_rate = _check_baud_rate(speed_baud_rate); new_tc.c_cflag |= (CLOCAL | CREAD);//Enable in default. /* *Set baud rate. e.g B115200 is 115200 bauds. */ cfsetispeed(&new_tc, valid_baud_rate);//input speed cfsetospeed(&new_tc, valid_baud_rate);//output speed /* *Set parity. */ switch(parity) { case 'n': case 'N': new_tc.c_cflag &= ~PARENB; //Disable parity. break; case 'o': case 'O': new_tc.c_cflag |= PARENB; //Enable parity. new_tc.c_cflag |= PARODD; //Odd parity. break; case 'e': case 'E': new_tc.c_cflag |= PARENB; //Enable parity. new_tc.c_cflag &= ~PARODD; //even parity. break; } /* *Set data bits. */ new_tc.c_cflag &= ~CSIZE; switch(data_bits) { case 5: break; case 6: break; case 7: new_tc.c_cflag |= CS7; break; case 8: new_tc.c_cflag |= CS8; break; } /* *Set stop bits. */ (stop_bits == 2)?(new_tc.c_cflag |= CSTOPB):(new_tc.c_cflag &= ~ CSTOPB); tcflush(fd,TCIFLUSH); //new_tc.c_cc[VTIME] = 0; //new_tc.c_cc[VMIN] = 1; if( tcsetattr(fd, TCSANOW, &new_tc) != 0) { rt_kprintf("Set port config fail!\n"); } }
int discard_buffer(int fd, boolean input) { return tcflush(fd, input ? TCIFLUSH : TCOFLUSH); }
int uart_open(struct uart *uart) { struct termios old_tio, new_tio; tcflag_t cflag = CS8 | CLOCAL| CREAD; int oflag = O_RDWR | O_NOCTTY; if (uart->blocking_mode == 0) oflag |= O_NONBLOCK; uart->uart_fd = open(uart->uart_path, oflag); if (uart->uart_fd < 0) return 0; tcgetattr(uart->uart_fd, &old_tio); memset(&new_tio, 0, sizeof(new_tio)); switch(uart->baud_rate) { case 1200: cflag |= B1200; break; case 2400: cflag |= B2400; break; case 4800: cflag |= B4800; break; case 9600: cflag |= B9600; break; case 19200: cflag |= B19200; break; case 38400: cflag |= B38400; break; case 57600: cflag |= B57600; break; case 115200: cflag |= B115200; break; default: close(uart->uart_fd); return 0; } if (uart->parity_check > 0) { cflag |= PARENB; if (uart->parity_check == 1) cflag |= PARODD; } if (uart->two_stop_bit == 1) cflag |= CSTOPB; new_tio.c_cflag = cflag; new_tio.c_iflag = IGNPAR; new_tio.c_oflag = 0; new_tio.c_lflag = 0; if (uart->blocking_mode == 0) new_tio.c_cc[VMIN] = 0; else new_tio.c_cc[VMIN] = 1; new_tio.c_cc[VTIME] = 0; tcflush(uart->uart_fd, TCIFLUSH); tcsetattr(uart->uart_fd, TCSANOW, &new_tio); return 1; }
void chronopic_flush(int serial_fd) { /* Vaciar los buffers de entrada y salida */ tcflush(serial_fd,TCIOFLUSH); }
/*----------------------------------------------------------------------------- * program start */ int main(int argc, char *argv[]) { fd_set fds; char rxbuf[50000]; char txbuf[1000]; int fd; int result; int txlen; int rxlen; bool tx = false; unsigned int cnt = 0; unsigned int missingRxCnt; if (argc != 3) { fprintf(stderr, "Usage: %s tty_device teststring\n", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDWR); if (fd == -1) { printf("cannot open %s\r\n", argv[1]); return 0; } SetDefaultPtyParam(fd); tcflush(fd, TCIOFLUSH); txlen = snprintf(txbuf, sizeof(txbuf), "%s%08x", TEST_STRING, cnt); write(fd, txbuf, txlen); missingRxCnt = 0; while (1) { FD_ZERO(&fds); FD_SET(fd, &fds); result = select(fd + 1, &fds, 0, 0, 0); // printf("result %d\n", result); if (result > 0) { if (FD_ISSET(fd, &fds)) { rxlen = read(fd, rxbuf, sizeof(rxbuf) - 1); rxbuf[rxlen] = 0; if (strstr(rxbuf, txbuf) != 0) { tx = true; missingRxCnt = 0; } else { printf("tx: %s rx: %s\n", txbuf, rxbuf); missingRxCnt++; } if (missingRxCnt == 10) { break; } } } if (tx) { cnt++; txlen = snprintf(txbuf, sizeof(txbuf), "%s%08x", TEST_STRING, cnt); write(fd, txbuf, txlen); tx = false; printf("tx%d\n", cnt); } } return 0; }
void serial_init_fd () { uint8_t *serial_dev; uint8_t *new_baud; int baud; // Check to see if someone specified a different serial port if (!mos_arg_check ("--sdev", &serial_dev)) serial_dev = DEFAULT_SERIAL_DEV; if (!mos_arg_check ("--sbaud", &new_baud)) { baud = DEFAULT_BAUDRATE; } else { if(strcmp(new_baud, "B2400") == 0) { baud = B2400; } else if(strcmp(new_baud, "B4800") == 0) { baud = B4800; } else if(strcmp(new_baud, "B9600") == 0) { baud = B9600; } else if(strcmp(new_baud, "B19200") == 0) { baud = B19200; } else if(strcmp(new_baud, "B38400") == 0) { baud = B38400; } else if(strcmp(new_baud, "B57600") == 0) { baud = B57600; } else if(strcmp(new_baud, "B115200") == 0) { baud = B115200; } else if(strcmp(new_baud, "B230400") == 0) { baud = B230400; } else { printf("Error in baud setting, try '--sbaud B57600'\n"); baud = DEFAULT_BAUDRATE; } printf("specified baud: %s\n", new_baud); } fflush(stdout); printf("opening serial\n"); fflush(stdout); // Init the actual serial device. The NOCTTY means this // terminal won't have any process control. (That way if a // control-C happens to come down the line we don't get dropped.) if (serialfd == -1) { // serialfd = open (serial_dev, O_RDWR | O_NOCTTY | O_NONBLOCK); serialfd = open (serial_dev, O_RDWR | O_NOCTTY); if (serialfd < 0) { printf("ERROR OPENING SERIAL\n"); perror (serial_dev); exit (-1); } } else { printf ("Serial port is already open\n"); return; } /* // Note that open() follows POSIX semantics: multiple open() calls to the same file will succeed // unless the TIOCEXCL ioctl is issued. This will prevent additional opens except by root-owned // processes. // See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details. if (ioctl(serialfd, TIOCEXCL) == -1) { printf("Error setting TIOCEXCL on %s.\n", serial_dev); return; } // Now that the device is open, clear the O_NONBLOCK flag so subsequent I/O will block. // See fcntl(2) ("man 2 fcntl") for details. if (fcntl(serialfd, F_SETFL, 0) == -1) { printf("Error clearing O_NONBLOCK %s.\n", serial_dev); return; } */ tcgetattr (serialfd, &oldtio); // save current port settings // Setup new serial port settings bzero (&newtio, sizeof (newtio)); // manually do what cfmakeraw () does since cygwin doesn't support it newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); newtio.c_oflag &= ~OPOST; newtio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); newtio.c_cflag &= ~(CSIZE | PARENB); newtio.c_cflag |= CS8; // newtio.c_cflag |= O_NOCTTY; newtio.c_iflag &= ~(INPCK | IXOFF | IXON); newtio.c_cflag &= ~(HUPCL | CSTOPB | CRTSCTS); newtio.c_cflag |= (CLOCAL | CREAD); // set input mode (non-canonical, no echo,...) newtio.c_lflag = 0; newtio.c_cc[VTIME] = 0; // min time between chars (*.1sec) newtio.c_cc[VMIN] = 1; // min number of chars for read cfsetispeed (&newtio, baud); cfsetospeed (&newtio, baud); tcflush (serialfd, TCIFLUSH); tcsetattr (serialfd,TCSANOW,&newtio); printf("done.\n"); }
ATMO_BOOL CMoMoConnection::OpenConnection() { #if defined(_ATMO_VLC_PLUGIN_) char *serdevice = m_pAtmoConfig->getSerialDevice(); if(!serdevice) return ATMO_FALSE; #else int portNummer = m_pAtmoConfig->getComport(); m_dwLastWin32Error = 0; if(portNummer < 1) return ATMO_FALSE; // make no real sense;-) #endif CloseConnection(); #if !defined(_ATMO_VLC_PLUGIN_) char serdevice[16]; // com4294967295 sprintf(serdevice,"com%d",portNummer); #endif #if defined(_WIN32) m_hComport = CreateFileA(serdevice, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(m_hComport == INVALID_HANDLE_VALUE) { // we have a problem here can't open com port... somebody else may use it? // m_dwLastWin32Error = GetLastError(); return ATMO_FALSE; } /* change serial settings (Speed, stopbits etc.) */ DCB dcb; // für comport-parameter dcb.DCBlength = sizeof(DCB); GetCommState (m_hComport, &dcb); // ger current serialport settings dcb.BaudRate = 9600; // set speed dcb.ByteSize = 8; // set databits dcb.Parity = NOPARITY; // set parity dcb.StopBits = ONESTOPBIT; // set one stop bit SetCommState (m_hComport, &dcb); // apply settings #else int bconst = B9600; m_hComport = open(serdevice,O_RDWR |O_NOCTTY); if(m_hComport < 0) { return ATMO_FALSE; } struct termios tio; memset(&tio,0,sizeof(tio)); tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL); tio.c_iflag = (INPCK | BRKINT); cfsetispeed(&tio, bconst); cfsetospeed(&tio, bconst); if(!tcsetattr(m_hComport, TCSANOW, &tio)) { tcflush(m_hComport, TCIOFLUSH); } else { // can't change parms close(m_hComport); m_hComport = -1; return false; } #endif return true; }
int main(int argc, char **argv) { int opt; int epoll_fd, serial_fd, e131_fd; uint16_t universe = 0x0001; char *device = NULL; speed_t baud_rate = B0; struct epoll_event epoll_events[MAX_EPOLL_EVENTS]; int nfds, i; e131_packet_t e131_packet; e131_error_t e131_error; uint8_t last_seq_number = 0x00; // program options while ((opt = getopt(argc, argv, "hu:d:b:")) != -1) { switch (opt) { case 'h': show_usage(argv[0]); exit(EXIT_SUCCESS); case 'u': sscanf(optarg, "%" SCNu16, &universe); if (universe < 0x0001 || universe > 0xf9ff) { fprintf(stderr, "error: universe must be between 1-63999\n"); exit(EXIT_FAILURE); } break; case 'd': device = optarg; break; case 'b': baud_rate = parse_baud_rate(optarg); if (baud_rate == B0) { fprintf(stderr, "error: invalid baud rate: %s\n", optarg); exit(EXIT_FAILURE); } break; default: fprintf(stderr, "Try '%s -h' for more information.\n", argv[0]); exit(EXIT_FAILURE); } } if (device == NULL || baud_rate == B0) { fprintf(stderr, "error: you must specify serial device and baud rate\n"); show_usage(argv[0]); exit(EXIT_FAILURE); } // create an epoll file descriptor if ((epoll_fd = epoll_create(1)) < 0) err(EXIT_FAILURE, "epoll_create1"); // open serial device and initialise if ((serial_fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) err(EXIT_FAILURE, "serial device open"); init_serial(serial_fd, baud_rate); epoll_add_fd(epoll_fd, serial_fd); fprintf(stderr, "serial device '%s' opened\n", device); // open E1.31 socket and join multicast group for the universe if ((e131_fd = e131_socket()) < 0) err(EXIT_FAILURE, "e131_socket"); if (e131_bind(e131_fd, E131_DEFAULT_PORT) < 0) err(EXIT_FAILURE, "e131_bind"); if (e131_multicast_join(e131_fd, universe) < 0) err(EXIT_FAILURE, "e131_multicast_join"); epoll_add_fd(epoll_fd, e131_fd); fprintf(stderr, "E1.31 multicast server listening on port %d\n", E131_DEFAULT_PORT); // bridge E1.31 data to AdaLight fprintf(stderr, "bridging E1.31 (sACN) to AdaLight, use CTRL+C to stop\n"); for (;;) { // wait for an epoll event if ((nfds = epoll_wait(epoll_fd, epoll_events, MAX_EPOLL_EVENTS, -1)) < 0) err(EXIT_FAILURE, "epoll_wait"); // check received epoll events for (i=0; i<nfds; i++) { if (epoll_events[i].data.fd == serial_fd) { // serial port data received tcflush(serial_fd, TCIFLUSH); continue; } if (epoll_events[i].data.fd == e131_fd) { // E1.31 network data received if (e131_recv(e131_fd, &e131_packet) < 0) err(EXIT_FAILURE, "e131_recv"); if ((e131_error = e131_pkt_validate(&e131_packet)) != E131_ERR_NONE) { fprintf(stderr, "e131_pkt_validate: %s\n", e131_strerror(e131_error)); continue; } if (e131_pkt_discard(&e131_packet, last_seq_number)) { fprintf(stderr, "warning: out of order E1.31 packet received\n"); last_seq_number = e131_packet.frame.seq_number; continue; } send_adalight(serial_fd, e131_packet.dmp.prop_val + 1, \ ntohs(e131_packet.dmp.prop_val_cnt) - 1); last_seq_number = e131_packet.frame.seq_number; } } } // finished close(e131_fd); close(serial_fd); close(epoll_fd); exit(EXIT_SUCCESS); }
void serialFlushInput(SerialPort *SP) { tcflush(SP->comPort, TCIFLUSH); }
/******************************************************************************* ** ** Function userial_vendor_open ** ** Description Open the serial port with the given configuration ** ** Returns device fd ** *******************************************************************************/ int userial_vendor_open(tUSERIAL_CFG *p_cfg) { uint32_t baud; uint8_t data_bits; uint16_t parity; uint8_t stop_bits; vnd_userial.fd = -1; if (!userial_to_tcio_baud(p_cfg->baud, &baud)) { return -1; } if(p_cfg->fmt & USERIAL_DATABITS_8) data_bits = CS8; else if(p_cfg->fmt & USERIAL_DATABITS_7) data_bits = CS7; else if(p_cfg->fmt & USERIAL_DATABITS_6) data_bits = CS6; else if(p_cfg->fmt & USERIAL_DATABITS_5) data_bits = CS5; else { ALOGE("userial vendor open: unsupported data bits"); return -1; } if(p_cfg->fmt & USERIAL_PARITY_NONE) parity = 0; else if(p_cfg->fmt & USERIAL_PARITY_EVEN) parity = PARENB; else if(p_cfg->fmt & USERIAL_PARITY_ODD) parity = (PARENB | PARODD); else { ALOGE("userial vendor open: unsupported parity bit mode"); return -1; } if(p_cfg->fmt & USERIAL_STOPBITS_1) stop_bits = 0; else if(p_cfg->fmt & USERIAL_STOPBITS_2) stop_bits = CSTOPB; else { ALOGE("userial vendor open: unsupported stop bits"); return -1; } ALOGI("userial vendor open: opening %s", vnd_userial.port_name); if ((vnd_userial.fd = open(vnd_userial.port_name, O_RDWR|O_NOCTTY)) == -1) { ALOGE("userial vendor open: unable to open %s", vnd_userial.port_name); return -1; } tcflush(vnd_userial.fd, TCIOFLUSH); tcgetattr(vnd_userial.fd, &vnd_userial.termios); cfmakeraw(&vnd_userial.termios); /* Set UART Control Modes */ vnd_userial.termios.c_cflag |= CLOCAL; vnd_userial.termios.c_cflag |= (CRTSCTS | stop_bits); tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); /* set input/output baudrate */ cfsetospeed(&vnd_userial.termios, baud); cfsetispeed(&vnd_userial.termios, baud); tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); tcflush(vnd_userial.fd, TCIOFLUSH); #if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) userial_ioctl_init_bt_wake(vnd_userial.fd); #endif ALOGI("device fd = %d open", vnd_userial.fd); return vnd_userial.fd; }
void serialFlushOutput(SerialPort *SP) { tcflush(SP->comPort, TCOFLUSH); }
void hokuyo::Laser::open(const char * port_name) { if (portOpen()) close(); // Make IO non blocking. This way there are no race conditions that // cause blocking when a badly behaving process does a read at the same // time as us. Will need to switch to blocking for writes or errors // occur just after a replug event. laser_fd_ = ::open(port_name, O_RDWR | O_NONBLOCK | O_NOCTTY); read_buf_start = read_buf_end = 0; if (laser_fd_ == -1) { const char *extra_msg = ""; switch (errno) { case EACCES: extra_msg = "You probably don't have premission to open the port for reading and writing."; break; case ENOENT: extra_msg = "The requested port does not exist. Is the hokuyo connected? Was the port name misspelled?"; break; } HOKUYO_EXCEPT(hokuyo::Exception, "Failed to open port: %s. %s (errno = %d). %s", port_name, strerror(errno), errno, extra_msg); } try { struct flock fl; fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_pid = getpid(); if (fcntl(laser_fd_, F_SETLK, &fl) != 0) HOKUYO_EXCEPT(hokuyo::Exception, "Device %s is already locked. Try 'lsof | grep %s' to find other processes that currently have the port open.", port_name, port_name); // Settings for USB? struct termios newtio; tcgetattr(laser_fd_, &newtio); memset (&newtio.c_cc, 0, sizeof (newtio.c_cc)); newtio.c_cflag = CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = 0; // activate new settings tcflush (laser_fd_, TCIFLUSH); if (tcsetattr (laser_fd_, TCSANOW, &newtio) < 0) HOKUYO_EXCEPT(hokuyo::Exception, "Unable to set serial port attributes. The port you specified (%s) may not be a serial port.", port_name); /// @todo tcsetattr returns true if at least one attribute was set. Hence, we might not have set everything on success. usleep (200000); // Some models (04LX) need to be told to go into SCIP2 mode... laserFlush(); // Just in case a previous failure mode has left our Hokuyo // spewing data, we send reset the laser to be safe. try { reset(); } catch (hokuyo::Exception &e) { // This might be a device that needs to be explicitely placed in // SCIP2 mode. // Note: Not tested: a device that is currently scanning in SCIP1.1 // mode might not manage to switch to SCIP2.0. setToSCIP2(); // If this fails then it wasn't a device that could be switched to SCIP2. reset(); // If this one fails, it really is an error. } querySensorConfig(); queryVersionInformation(); // In preparation for calls to get various parts of the version info. } catch (hokuyo::Exception& e) { // These exceptions mean something failed on open and we should close if (laser_fd_ != -1) ::close(laser_fd_); laser_fd_ = -1; throw e; } }
/*---------------------------------------------------------------------------*/ static void stty_telos(int fd) { struct termios tty; speed_t speed = slip_config_b_rate; int i; if(tcflush(fd, TCIOFLUSH) == -1) { LOG6LBR_FATAL("tcflush() : %s\n", strerror(errno)); exit(1); } if(tcgetattr(fd, &tty) == -1) { LOG6LBR_FATAL("tcgetattr() : %s\n", strerror(errno)); exit(1); } cfmakeraw(&tty); /* Nonblocking read. */ tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = 0; if(slip_config_flowcontrol) { tty.c_cflag |= CRTSCTS; } else { tty.c_cflag &= ~CRTSCTS; } tty.c_cflag &= ~HUPCL; tty.c_cflag &= ~CLOCAL; cfsetispeed(&tty, speed); cfsetospeed(&tty, speed); if(tcsetattr(fd, TCSAFLUSH, &tty) == -1) { LOG6LBR_FATAL("tcsetattr() : %s\n", strerror(errno)); exit(1); } #if 1 /* Nonblocking read and write. */ /* if(fcntl(fd, F_SETFL, O_NONBLOCK) == -1) err(1, "fcntl"); */ tty.c_cflag |= CLOCAL; if(tcsetattr(fd, TCSAFLUSH, &tty) == -1) { LOG6LBR_FATAL("tcsetattr() : %s\n", strerror(errno)); exit(1); } i = TIOCM_DTR; if(ioctl(fd, TIOCMBIS, &i) == -1) { LOG6LBR_FATAL("ioctl() : %s\n", strerror(errno)); exit(1); } #endif usleep(10 * 1000); /* Wait for hardware 10ms. */ /* Flush input and output buffers. */ if(tcflush(fd, TCIOFLUSH) == -1) { LOG6LBR_FATAL("tcflush() : %s\n", strerror(errno)); exit(1); } }
main(int argc, char *argv[]) { int fd,n_carac,n,retardo,i; /*Para Tx */ int fin_f=0; FILE *arch; struct termios oldtio,newtio; packet paquete; frame trama,trama_r;// trama_r es de retransmision /*Para el autoamata */ TAutomat *automata = NULL; TEntity entidad1; TEntity *active_en = &entidad1; Argumentos argu1; Argumentos *argu= &argu1; int n_rtx;//numero de retransmisiones argu->paquete= &paquete; //con esto evito hacer un malloc /*Para la RX, es la se�l*/ struct sigaction saio; /* definicion de accion de segnal */ printf("abre archivo \n" ); /* Abre el dispositivo modem para lectura y escritura y no como controlador tty porque no queremos que nos mate si el ruido de la linea envia un CRTL-C Se debe usar O_NONBLOCK ????????? */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/); if (fd <0) {perror(MODEMDEVICE); exit(-1); } /***********SIGIO************************************************************************/ /* instala el manejador de segnal antes de hacer asincrono el dispositivo */ saio.sa_handler = signal_handler_IO; /* especifica la acci� que se va a asociar con SIGIO*/ saio.sa_flags = SA_NOMASK; /*especifica un cjto de opciones que modifican el comportamiento del proceso de manejo de se�l*/ saio.sa_restorer = NULL; /*es algo caduco ya no se usa*/ sigaction(SIGIO,&saio,NULL);/*sigaction, permite especificar explicitamente el comportamiento de los gestores de se�les el reiniciado de las llamadas del sistemaesta deshabilitado por defecto, pero puede activarse si se especica el flag de se�l SA RESTART*/ /*int fcntl(int fd, int ope, long arg); fcntl realiza una ope de control sobre el fichero refenciado por fd*/ /* permite al proceso recibir SIGIO */ fcntl(fd, F_SETOWN, getpid());/*F_SETOWN Establece el ID de proceso o el grupo de procesos que recibir�las se�les SIGIO para los eventos sobre el descriptor fd.*/ /* Hace el descriptor de archivo asincrono*/ fcntl(fd, F_SETFL, FASYNC); /*F_SETFL Asigna a las banderas de descriptor el valor asignado por FASYNC que se correspondan*/ /********FIN_SIGIO***************************************************************************/ tcgetattr(fd,&oldtio); /* Almacenamos la configuracion actual del puerto */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /* Ignore bytes with parity errors and make terminal raw and dumb. No hace falta ICRNL xk aki transmito, no recibo */ /***********************Debo usar ICRNL?????*/ newtio.c_iflag = IGNPAR /*| ICRNL*/; /* Raw output. */ newtio.c_oflag = 0; /* Don't echo characters because if you connect to a host it or your modem will echo characters for you. Don't generate signals. ********************************Se debe usar ICANON ????? */ newtio.c_lflag = ICANON;// 0; /* blocking read until 1 char arrives */ newtio.c_cc[VMIN]=1; newtio.c_cc[VTIME]=0; /* Ahora limpiamos la linea del modem y activamos la configuracion del puerto */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* terminal settings done, now handle output */ printf("abre archivo : %s \n",argv[3]); arch = fopen(argv[3],"r"); if (arch == NULL) {printf("Error al abrir el fichero \n"); exit(-1); } /* guardamos el numero de n*/ printf(" arch = %i \n", arch ); retardo= *argv[2]; retardo= retardo * 100000; n = atoi(argv[1]); printf(" n = %i \n", n); if (n>260){ perror("Lo siento sale del rango de SDU \n");exit(-1); } /*Guardo el n de retransmisiones*/ n_rtx =atoi(argv[4]); /*Guardo temporizador*/ argu->tempo =atoi(argv[5]); /*Inicalizo variables de estadisticas*/ argu->tr_perdidas =0; argu->tra_retx = 0; /* Define automata */ /*Se inicializa la matriz de mi automata */ automata = s1_automat_define( ); /*Empieza en el estado inicial */ entidad1.myCurrentState= STATE_INITIAL; printf(" ***************** Se ha creado el automata y se inicializa \n"); //printf("Estoy en el estado = %i ",argu->active_en->myCurrentState); /* ********************** */ /*Se envia primera trama*/ if ( (argu->trama_e = (frame *) malloc(sizeof(frame)) )== NULL) { perror("No hay suficiente espacio de memoria \n"); exit (-1); } argu->paquete->n = n; argu->n_rtx=n_rtx; /*Se le pasa el puerto*/ argu->fde = fd; /*argu.paquete.data== argu y paquete son pteros a struct */ memset(argu->paquete->data,'\0',sizeof(argu->paquete->data)); /*devuelve el nde caract leidos*de arch */ n_carac= from_network_layer (argu->paquete,arch); /*============================================================== /*=======================================================*/ /* */ argu->retardo = retardo; argu->sec_actual= 'A'; argu->sec_siguiente='B'; printf(" Empieza el retardo \n" ); //usleep(retardo); printf(" 1) el retardo1 es = %i \n", retardo ); //usleep(argu->retardo); printf(" 2) Retardo2 es = %i \n", argu->retardo ); argu->active_en=active_en; printf("Estoy en el estado = %i \n",argu->active_en->myCurrentState); printf(" Secuencia antes enviar %c\n", argu->trama_e->address); /* entidad , automata, evento, argumentos de evento */ automat_transit(argu->active_en,automata,EV_INI, argu); printf(" Secuencia despues de enviar %c \n", argu->trama_e->address); trama_r = trama; printf("Estoy en el estado = %i \n",argu->active_en->myCurrentState); printf(" va al bucle \n"); fin_f=feof(arch); while (feof(arch)==0) { printf("entra en el bucle \n"); /*se guarda el n de caracte que queremos leer*/ paquete.n = n; /*argu.paquete.data== argu y paquete son pteros a struct */ memset(argu->paquete->data,'\0',sizeof(argu->paquete->data)); /*devuelve el nde caract leidos*de arch */ n_carac= from_network_layer (argu->paquete,arch); // automat_transit(argu->active_en,automata,ACK, argu); /* ===========================================================================*/ //espero ACK recibe_ACK(argu, automata,fin_f); fin_f=feof(arch); //******************************************************* } //while recibe_ACK(argu, automata,fin_f); /* //Se envia la trama de finalizacion trama.data[0]='\0'; trama.control='T';//0x09; printf("Se envia la trama vacia %s: ,tam : %d \n",trama.data,strlen(trama.data)); to_physical_layer(&trama,fd); automat_transit(active_en,automata,ACK_0, argu); */ //usleep(retardo); usleep(100000); tcsetattr(fd,TCSANOW,&oldtio); /* restore old modem setings */ close(fd); fclose(arch); /*Se impirmen las estadisticas*/ printf(" ************************************************** \n"); printf(" (TX) Numero de Tramas Retransmitidas es : %i \n",argu->tra_retx); printf(" (TX/RX) Numero de Tramas Perdidas es : %i \n",argu->tr_perdidas); argu->active_en=active_en; free (argu->trama_e); automat_destroy( automata ); }
static int open_device(uart_ctx_t* ctx, char* name, size_t max_namelen) { int flags; int tty_fd = -1; int fd = -1; if (strcmp(name, "//pty") == 0) { #ifdef HAVE_PTY char slave_name[UART_MAX_DEVICE_NAME]; if ((fd = local_openpt(O_RDWR|O_NOCTTY)) < 0) { DEBUGF("posix_openpt failed : %s", strerror(errno)); return -1; } if (grantpt(fd) < 0) { DEBUGF("grantpt failed : %s", strerror(errno)); goto error; } if (unlockpt(fd) < 0) { DEBUGF("unlockpt failed : %s", strerror(errno)); goto error; } if (local_ptsname_r(fd, slave_name, sizeof(slave_name)) < 0) { DEBUGF("ptsname_r failed : %s", strerror(errno)); goto error; } if (strlen(slave_name) >= max_namelen) { errno = ERANGE; goto error; } strcpy(name, slave_name); if ((flags = fcntl(fd, F_GETFL, 0)) < 0) { DEBUGF("fcntl: F_GETFL failed : %s", strerror(errno)); goto error; } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { DEBUGF("fcntl: F_SETFL failed : %s", strerror(errno)); goto error; } #else errno = ENOTSUP; return -1; #endif } if ((tty_fd = open(name, O_RDWR|O_NDELAY|O_NOCTTY)) < 0) goto error; // non-blocking!!! if ((flags = fcntl(tty_fd, F_GETFL, 0)) < 0) { DEBUGF("fcntl: F_GETFL tty_fd failed : %s", strerror(errno)); goto error; } if (fcntl(tty_fd, F_SETFL, flags | O_NONBLOCK) < 0) { DEBUGF("fcntl: F_SETFL tty_fd failed : %s", strerror(errno)); goto error; } tcflush(tty_fd, TCOFLUSH); tcflush(tty_fd, TCIFLUSH); ctx->tty_fd = tty_fd; ctx->fd = (fd>=0) ? fd : tty_fd; DEBUGF("open_device: tty_fd=%d fd=%d", ctx->tty_fd, ctx->fd); return tty_fd; error: { int save_errno = errno; if (fd >= 0) close(fd); if ((fd != tty_fd) && (tty_fd >= 0)) close(tty_fd); errno = save_errno; } return -1; }