0

I am trying to initiate serial communication from the code below. The problem however is that I have to open the hyper terminal with the same settings and then close it, Before running the code below inside another program written in C for the code to work as intended. I would very much like to skip the initial step with the hyper terminal but I haven't been able to figure out what it is that is causing this odd behavior. I have posted the code for the initiation below as well as my code for kbhit() that possibly could be the reason for this behavior. I would be extremely thankful if someone could tell my how I could solve this.

int kbhit(){ //Detects if a key has been pressed, 1 if true else 0 
  struct termios oldt, newt;
  int ch;
  int oldf;
  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0;
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
  ch = getchar();
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF){
    ungetc(ch, stdin); //Puts back the pressed key to the stack
    return 1;
  }
  return 0;
}  

The initiation code for the serial communication through the USB port is displayed below:

#include "USB.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
/* baudrate settings are defined in <asm/termbits.h>, which is
 * included by <termios.h> */
#ifndef BAUDRATE
#define BAUDRATE B9600  //the desired baud rate
#endif
#define _POSIX_SOURCE 1     /* POSIX compliant source */
static int fd, c, res;
static struct termios oldtio, newtio;
static char *device;
int USB_init(char *modemdevice){
    device = modemdevice;
    fd = open (device, O_RDWR | O_NOCTTY|O_NONBLOCK );//|O_NONBLOCK has been added
    if (fd < 0){
      perror (device);
      exit(-1);
    }
    tcgetattr (fd, &oldtio);    /* save current settings */
    bzero (&newtio, sizeof (newtio));   /* clear struct for new port settings */
    /* 
     *BAUDRATE: Set bps rate. 
     *CS8     : 8n1 (8bit,no parity,1 stop bit)
     *CLOCAL  : local connection, no modem contol
     *CREAD   : enable receiving characters
     **/
    newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR | ICRNL;
    /*
     * ICANON  : enable canonical input
     *           disable all echo functionality, and don't send signals to calling program*/
#if 1
    newtio.c_lflag = ICANON;
#else
    newtio.c_lflag = 0;
#endif 
     /* initialize all control characters 
     * default values can be found in /usr/include/termios.h, and are given
     * in the comments, but we don't need them here*/
    newtio.c_cc[VINTR] = 0; /* Ctrl-c */
    newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */
    newtio.c_cc[VERASE] = 0;    /* del */
    newtio.c_cc[VKILL] = 0; /* @ */
    newtio.c_cc[VEOF] = 4;  /* Ctrl-d */
    newtio.c_cc[VTIME] = 10; // 0 before
    newtio.c_cc[VMIN] = 0;  /* blocking read until 0 character arrives*/
    newtio.c_cc[VSWTC] = 0; /* '\0' */
    newtio.c_cc[VSTART] = 0;    /* Ctrl-q */
    newtio.c_cc[VSTOP] = 0; /* Ctrl-s */
    newtio.c_cc[VSUSP] = 0; /* Ctrl-z */
    newtio.c_cc[VEOL] = 0;  /* '\0' */
    newtio.c_cc[VREPRINT] = 0;  /* Ctrl-r */
    newtio.c_cc[VDISCARD] = 0;  /* Ctrl-u */
    newtio.c_cc[VWERASE] = 0;   /* Ctrl-w */
    newtio.c_cc[VLNEXT] = 0;    /* Ctrl-v */
    newtio.c_cc[VEOL2] = 0; /* '\0' */
    tcflush (fd, TCIFLUSH);
    tcsetattr (fd, TCSANOW, &newtio);
    return fd;
}

void USB_cleanup(int ifd){
    if(ifd != fd){
        fprintf(stderr, "WARNING! file descriptor != the one returned by USB_init()\n");
    }
    /* restore the old port settings */
    tcsetattr (ifd, TCSANOW, &oldtio);
}
dsolimano
  • 8,870
  • 3
  • 48
  • 63
Henrik
  • 405
  • 1
  • 8
  • 19
  • *"serial communication through the USB port"* -- If you're using a USB-to-RS232 adapter (or a USB gadget that emulates a serial port device), then the fact that the USBus is involved is totally transparent to the application program. So naming your functions **USB_init()** and **USB_cleanup()** when they do nothing with respect to USB is misleading. `bzero (&newtio, sizeof (newtio))` is a common but wrong method of initializing a **termios** structure. Study [Setting Terminal Modes Properly](http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html#SEC237) – sawdust May 26 '14 at 01:08
  • Also study [Serial Programming Guide for POSIX Operating Systems](http://www.cmrr.umn.edu/~strupp/serial.html). Do not use the bad examples from http://www.tldp.org/HOWTO/pdf/Serial-Programming-HOWTO.pdf – sawdust May 26 '14 at 01:14

0 Answers0